Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/control/upnp_server/cds/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 7 kB image not shown  

Quelle  Item.cpp   Sprache: C

 

/*****************************************************************************
 * Item.cpp
 *****************************************************************************
 * Copyright © 2024 VLC authors and VideoLAN
 *
 * Authors: Alaric Senat <alaric@videolabs.io>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <chrono>
#include <sstream>

#include "../utils.hpp"
#include "Item.hpp"

namespace cds
{

Item::Item(const int64_t id, const ml::MediaLibraryContext &ml) noexcept :
    Object(id, -1, nullptr, Object::Type::Item),
    medialib_(ml)
{}

template <typename Rep, typename Pediod = std::ratio<1>>
static std::string duration_to_string(const char *fmt, std::chrono::duration<Rep, Pediod> duration)
{
    char ret[32] = {0};
    using namespace std::chrono;
    // Substract 1 hour because std::localtime starts at 1 AM
    const time_t sec = duration_cast<seconds>(duration - 1h).count();
    const size_t size = std::strftime(ret, sizeof(ret), fmt, std::localtime(&sec));
    return std::string{ret, size};
}

static xml::Element make_resource(xml::Document &doc,
                                  const vlc_ml_media_t &media,
                                  const std::vector<utils::MediaTrackRef> v_tracks,
                                  const std::vector<utils::MediaFileRef> main_files,
                                  const std::string &file_extension)
{
    const auto &profile_name = "native";
    const char *mux = file_extension.c_str();

    const std::string url_base = utils::get_server_url();
    const std::string url =
        url_base + "media/" + profile_name + "/" + std::to_string(media.i_id) + "." + mux;

    auto elem = doc.create_element("res", doc.create_text_node(url.c_str()));
    const auto media_duration =
        duration_to_string("%H:%M:%S", std::chrono::milliseconds(media.i_duration));
    elem.set_attribute("duration", media_duration.c_str());

    if (media.i_type == VLC_ML_MEDIA_TYPE_VIDEO)
    {
        std::stringstream resolution;
        if (v_tracks.size() >= 1)
        {
            const vlc_ml_media_track_t &vtrack = v_tracks[0];

            resolution << vtrack.v.i_width << 'x' << vtrack.v.i_height;
        }
        elem.set_attribute("resolution", resolution.str().c_str());
    }

    const auto mime_type = utils::get_mimetype(media.i_type, mux);
    const auto protocol_info = utils::http::get_dlna_extra_protocol_info(mime_type);

    elem.set_attribute("protocolInfo", protocol_info.c_str());

    if (main_files.size() >= 1)
    {
        elem.set_attribute("size", std::to_string(main_files[0].get().i_size).c_str());
    }

    return elem;
};

static void
dump_resources(xml::Element &dest, const vlc_ml_media_t &media, const std::string &file_extension)
{
    xml::Document &doc = dest.owner;

    const auto v_tracks = utils::get_media_tracks(media, VLC_ML_TRACK_TYPE_VIDEO);
    const auto main_files = utils::get_media_files(media, VLC_ML_FILE_TYPE_MAIN);

    dest.add_child(make_resource(doc, media, v_tracks, main_files, file_extension));

    // Thumbnails
    for (int i = 0; i < VLC_ML_THUMBNAIL_SIZE_COUNT; ++i)
    {
        const auto &thumbnail = media.thumbnails[i];
        if (thumbnail.i_status != VLC_ML_THUMBNAIL_STATUS_AVAILABLE)
            continue;
        const auto thumbnail_extension = utils::file_extension(std::string(thumbnail.psz_mrl));
        const auto url = utils::thumbnail_url(media, static_cast<vlc_ml_thumbnail_size_t>(i));
        auto elem = doc.create_element("res", doc.create_text_node(url.c_str()));

        const utils::MimeType mime{"image", "jpeg"};
        const auto protocol_info = utils::http::get_dlna_extra_protocol_info(mime);
        elem.set_attribute("protocolInfo", protocol_info.c_str());

        dest.add_child(std::move(elem));
    }

    // Subtitles, for now we only share the first available subtitle file.
    const auto subtitles = utils::get_media_files(media, VLC_ML_FILE_TYPE_SUBTITLE);
    if (!subtitles.empty())
    {
        const vlc_ml_file_t &sub = subtitles.front();
        const auto file_extension = utils::file_extension(sub.psz_mrl);
        const std::string url = utils::get_server_url() + "subtitle/" + std::to_string(media.i_id) +
                                "." + file_extension;

        auto res = doc.create_element("res", doc.create_text_node(url.c_str()));
        res.set_attribute("protocolInfo", ("http-get:*:text/" + file_extension + ":*").c_str());
        dest.add_child(std::move(res));
    }
}

void Item::dump_mlobject_metadata(xml::Element &dest,
                                  const vlc_ml_media_t &media,
                                  const ml::MediaLibraryContext &ml)
{

    if (media.p_files->i_nb_items == 0)
        return;

    const vlc_ml_file_t &file = media.p_files->p_items[0];

    const std::string file_extension = utils::file_extension(file.psz_mrl);

    const char *object_class = nullptr;
    switch (media.i_type)
    {
        case VLC_ML_MEDIA_TYPE_AUDIO:
            object_class = "object.item.audioItem";
            break;
        case VLC_ML_MEDIA_TYPE_VIDEO:
            object_class = "object.item.videoItem";
            break;
        default:
            return;
    }

    const std::string date = std::to_string(media.i_year) + "-01-01";

    xml::Document &doc = dest.owner;

    dest.add_children(doc.create_element("upnp:class", doc.create_text_node(object_class)),
                      doc.create_element("dc:title", doc.create_text_node(media.psz_title)),
                      doc.create_element("dc:date", doc.create_text_node(date.c_str())));

    switch (media.i_subtype)
    {
        case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
        {
            const auto album = ml::Album::get(ml, media.album_track.i_album_id);
            if (album != nullptr)
            {
                const auto album_thumbnail_url = utils::album_thumbnail_url(*album);
                dest.add_children(
                    doc.create_element("upnp:album", doc.create_text_node(album->psz_title)),
                    doc.create_element("upnp:artist", doc.create_text_node(album->psz_artist)),
                    doc.create_element("upnp:albumArtURI",
                                       doc.create_text_node(album_thumbnail_url.c_str())));
            }
            break;
        }
        default:
            break;
    }

    dump_resources(dest, media, file_extension);
}

void Item::dump_metadata(xml::Element &dest, const Object::ExtraId &extra_id) const
{
    assert(extra_id.has_value());
    const auto media = ml::Media::get(medialib_, extra_id->ml_id);

    dump_mlobject_metadata(dest, *media.get(), medialib_);
}

} // namespace cds

Messung
CHZG
81999792

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.