[vlc-devel] [PATCH 04/17] qt/medialibrary: Create MLPlaylistMedia

Benjamin Arnaud benjamin.arnaud at videolabs.io
Fri Feb 19 10:25:28 UTC 2021


---
 modules/gui/qt/Makefile.am                    |   2 +
 .../gui/qt/medialibrary/mlplaylistmedia.cpp   | 236 ++++++++++++++++++
 .../gui/qt/medialibrary/mlplaylistmedia.hpp   |  99 ++++++++
 po/POTFILES.in                                |   2 +
 4 files changed, 339 insertions(+)
 create mode 100644 modules/gui/qt/medialibrary/mlplaylistmedia.cpp
 create mode 100644 modules/gui/qt/medialibrary/mlplaylistmedia.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 6c0516dbce..4365fda0f8 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -172,6 +172,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/medialibrary/mlplaylist.hpp \
 	gui/qt/medialibrary/mlplaylistlistmodel.cpp \
 	gui/qt/medialibrary/mlplaylistlistmodel.hpp \
+	gui/qt/medialibrary/mlplaylistmedia.cpp \
+	gui/qt/medialibrary/mlplaylistmedia.hpp \
 	gui/qt/menus/custom_menus.cpp \
 	gui/qt/menus/custom_menus.hpp \
 	gui/qt/menus/qml_menu_wrapper.cpp \
diff --git a/modules/gui/qt/medialibrary/mlplaylistmedia.cpp b/modules/gui/qt/medialibrary/mlplaylistmedia.cpp
new file mode 100644
index 0000000000..2eb9855fcc
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlplaylistmedia.cpp
@@ -0,0 +1,236 @@
+/*****************************************************************************
+ * Copyright (C) 2021 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ *****************************************************************************/
+
+#include "mlplaylistmedia.hpp"
+
+// VLC includes
+#include <qt.hpp>
+
+//-------------------------------------------------------------------------------------------------
+// Ctor / dtor
+//-------------------------------------------------------------------------------------------------
+
+MLPlaylistMedia::MLPlaylistMedia(vlc_medialibrary_t * ml, const vlc_ml_media_t * data)
+    : MLItem(MLItemId(data->i_id, VLC_ML_PARENT_UNKNOWN))
+    , m_ml(ml)
+    , m_type(data->i_type)
+    , m_title(qfu(data->psz_title))
+    , m_thumbnail(qfu(data->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl))
+    , m_duration(data->i_duration)
+    , m_progress(data->f_progress)
+    , m_playCount(data->i_playcount)
+    , m_handle(nullptr, [this](vlc_ml_event_callback_t * cb) {
+        assert(m_ml != nullptr);
+
+        vlc_ml_event_unregister_callback(m_ml, cb);
+    })
+{
+    for (const vlc_ml_file_t & file : ml_range_iterate<vlc_ml_file_t>(data->p_files))
+    {
+        if (file.i_type != VLC_ML_FILE_TYPE_MAIN)
+            continue;
+
+        //FIXME: Should we store every mrl ?
+        m_mrl = QUrl::fromEncoded(file.psz_mrl);
+    }
+
+    unsigned int width  = 0;
+    unsigned int height = 0;
+
+    unsigned int nbChannels = 0;
+
+    for(const vlc_ml_media_track_t & track
+        : ml_range_iterate<vlc_ml_media_track_t>(data->p_tracks))
+    {
+        if (track.i_type == VLC_ML_TRACK_TYPE_VIDEO)
+        {
+            width  = std::max(width,  track.v.i_width);
+            height = std::max(height, track.v.i_height);
+
+            m_video.push_back(
+            {
+                qfu(track.psz_codec),
+                qfu(track.psz_language),
+                track.v.i_fpsNum
+            });
+        }
+        else if (track.i_type == VLC_ML_TRACK_TYPE_AUDIO)
+        {
+            nbChannels = std::max(nbChannels, track.a.i_nbChannels);
+
+            m_audio.push_back(
+            {
+                qfu(track.psz_codec),
+                qfu(track.psz_language),
+                track.a.i_nbChannels, track.a.i_sampleRate
+            });
+        }
+    }
+
+    if (nbChannels >= 8)
+        m_channel = "7.1";
+    else if (nbChannels >= 6)
+        m_channel = "5.1";
+    else
+        m_channel = "";
+
+    if (width >= 7680 && height >= 4320)
+        m_resolution = "8K";
+    else if (width >= 3840 && height >= 2160)
+        m_resolution = "4K";
+    else if (width >= 1440 && height >= 1080)
+        m_resolution = "HD";
+    else if (width >= 720 && height >= 1280)
+        m_resolution = "720p";
+    else
+        m_resolution = "";
+}
+
+//-------------------------------------------------------------------------------------------------
+// Interface
+//-------------------------------------------------------------------------------------------------
+
+QString MLPlaylistMedia::getTitle() const
+{
+    return m_title;
+}
+
+// FIXME: We have the same code in MLVideo implementation.
+QString MLPlaylistMedia::getThumbnail()
+{
+    // NOTE: We don't need to generate a cover for audio media(s).
+    if (m_type != VLC_ML_MEDIA_TYPE_AUDIO
+        &&
+        (m_thumbnailStatus == VLC_ML_THUMBNAIL_STATUS_MISSING
+         ||
+         m_thumbnailStatus == VLC_ML_THUMBNAIL_STATUS_FAILURE))
+    {
+        m_handle.reset(vlc_ml_event_register_callback(m_ml, onMlEvent, this));
+
+        vlc_ml_media_generate_thumbnail(m_ml, getId().id, VLC_ML_THUMBNAIL_SMALL,
+                                        512, 320, 0.15);
+    }
+
+    return m_thumbnail;
+}
+
+//-------------------------------------------------------------------------------------------------
+
+QString MLPlaylistMedia::getDuration() const
+{
+    return MsToString(m_duration);
+}
+
+QString MLPlaylistMedia::getDurationShort() const
+{
+    return MsToString(m_duration, true);
+}
+
+//-------------------------------------------------------------------------------------------------
+
+QString MLPlaylistMedia::getResolutionName() const
+{
+    return m_resolution;
+}
+
+//-------------------------------------------------------------------------------------------------
+
+QString MLPlaylistMedia::getChannel() const
+{
+    return m_channel;
+}
+
+//-------------------------------------------------------------------------------------------------
+
+QString MLPlaylistMedia::getMRL() const
+{
+    return m_mrl.toEncoded();
+}
+
+QString MLPlaylistMedia::getMRLDisplay() const
+{
+    return m_mrl.toString(QUrl::PrettyDecoded | QUrl::RemoveUserInfo | QUrl::PreferLocalFile |
+                          QUrl::NormalizePathSegments);
+}
+
+//-------------------------------------------------------------------------------------------------
+
+float MLPlaylistMedia::getProgress() const
+{
+    return m_progress;
+}
+
+QString MLPlaylistMedia::getProgressTime() const
+{
+    return MsToString(m_duration * m_progress);
+}
+
+//-------------------------------------------------------------------------------------------------
+
+unsigned int MLPlaylistMedia::getPlayCount() const
+{
+    return m_playCount;
+}
+
+//-------------------------------------------------------------------------------------------------
+
+QList<VideoDescription> MLPlaylistMedia::getVideo() const
+{
+    return m_video;
+}
+
+QList<AudioDescription> MLPlaylistMedia::getAudio() const
+{
+    return m_audio;
+}
+
+//-------------------------------------------------------------------------------------------------
+// Private events
+//-------------------------------------------------------------------------------------------------
+
+/* static */ void MLPlaylistMedia::onMlEvent(void * data, const vlc_ml_event_t * event)
+{
+    MLPlaylistMedia * self = static_cast<MLPlaylistMedia *>(data);
+
+    self->onMlEvent(event);
+}
+
+void MLPlaylistMedia::onMlEvent(const vlc_ml_event_t * event)
+{
+    if (event->i_type != VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED
+        ||
+        event->media_thumbnail_generated.i_size != VLC_ML_THUMBNAIL_SMALL
+        ||
+        event->media_thumbnail_generated.p_media->i_id != getId().id)
+        return;
+
+    if (event->media_thumbnail_generated.b_success == false)
+    {
+        m_thumbnailStatus = VLC_ML_THUMBNAIL_STATUS_FAILURE;
+
+        return;
+    }
+
+    vlc_ml_thumbnail_size_t size = event->media_thumbnail_generated.i_size;
+
+    m_thumbnail = qfu(event->media_thumbnail_generated.p_media->thumbnails[size].psz_mrl);
+
+    m_thumbnailStatus = VLC_ML_THUMBNAIL_STATUS_AVAILABLE;
+
+    vlc_ml_event_unregister_from_callback(m_ml, m_handle.release());
+}
diff --git a/modules/gui/qt/medialibrary/mlplaylistmedia.hpp b/modules/gui/qt/medialibrary/mlplaylistmedia.hpp
new file mode 100644
index 0000000000..a1e0da2304
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlplaylistmedia.hpp
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * Copyright (C) 2021 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ *****************************************************************************/
+
+#ifndef MLPLAYLISTMEDIA_H
+#define MLPLAYLISTMEDIA_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// MediaLibrary includes
+// NOTE: We need that header for VideoDescription and AudioDescription.
+#include "mlvideo.hpp"
+
+// Qt includes
+#include <QUrl>
+
+// Forward declarations
+class vlc_medialibrary_t;
+
+class MLPlaylistMedia : public MLItem
+{
+public:
+    MLPlaylistMedia(vlc_medialibrary_t * ml, const vlc_ml_media_t * data);
+
+public: // Interface
+    QString getTitle() const;
+
+    QString getThumbnail();
+
+    QString getDuration     () const;
+    QString getDurationShort() const;
+
+    QString getResolutionName() const;
+
+    QString getChannel() const;
+
+    QString getMRL       () const;
+    QString getMRLDisplay() const;
+
+    float   getProgress    () const;
+    QString getProgressTime() const;
+
+    unsigned int getPlayCount() const;
+
+    QList<VideoDescription> getVideo() const;
+    QList<AudioDescription> getAudio() const;
+
+private: // Events
+    static void onMlEvent(void * data, const vlc_ml_event_t * event);
+
+    void onMlEvent(const vlc_ml_event_t * event);
+
+private: // Properties
+    vlc_medialibrary_t * m_ml;
+
+    vlc_ml_media_type_t m_type;
+
+    QString m_title;
+
+    QString                   m_thumbnail;
+    vlc_ml_thumbnail_status_t m_thumbnailStatus;
+
+    int64_t m_duration;
+
+    QString m_resolution;
+
+    QString m_channel;
+
+    QUrl m_mrl;
+
+    float   m_progress;
+    QString m_progressTime;
+
+    unsigned int m_playCount;
+
+    QList<VideoDescription> m_video;
+    QList<AudioDescription> m_audio;
+
+    std::unique_ptr<vlc_ml_event_callback_t,
+                    std::function<void(vlc_ml_event_callback_t*)>> m_handle;
+};
+
+#endif // MLPLAYLISTMEDIA_H
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 396418fb24..d765d78991 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -772,6 +772,8 @@ modules/gui/qt/medialibrary/mlfoldersmodel.cpp
 modules/gui/qt/medialibrary/mlfoldersmodel.hpp
 modules/gui/qt/medialibrary/mlplaylistlistmodel.cpp
 modules/gui/qt/medialibrary/mlplaylistlistmodel.hpp
+modules/gui/qt/medialibrary/mlplaylistmedia.cpp
+modules/gui/qt/medialibrary/mlplaylistmedia.hpp
 modules/gui/qt/menus/menus.cpp
 modules/gui/qt/menus/menus.hpp
 modules/gui/qt/qt.cpp
-- 
2.25.1



More information about the vlc-devel mailing list