From 196909f416b88664a0b62cc4261c78ba986aa6f6 Mon Sep 17 00:00:00 2001 From: RadRussianRus Date: Wed, 31 Mar 2021 23:29:41 +0300 Subject: [PATCH] Add support for setting cover with MPRIS Cherry-picked from https://github.com/telegramdesktop/tdesktop/pull/16074. --- .../platform/linux/linux_mpris_support.cpp | 160 ++++++++++++------ 1 file changed, 106 insertions(+), 54 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp b/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp index 82728bbb2..5dc9fd02a 100644 --- a/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_mpris_support.cpp @@ -11,13 +11,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/linux/base_linux_glibmm_helper.h" #include "media/audio/media_audio.h" #include "media/player/media_player_instance.h" +#include "data/data_file_origin.h" #include "data/data_document.h" +#include "data/data_document_media.h" #include "core/sandbox.h" #include "core/application.h" #include "core/core_settings.h" +#include "main/main_domain.h" +#include "main/main_account.h" +#include "main/main_session.h" #include "mainwindow.h" #include "app.h" +#include #include #include @@ -36,61 +42,63 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs; constexpr auto kSongType = AudioMsgId::Type::Song; constexpr auto kIntrospectionXML = R"INTROSPECTION( - - - - - - - - - - - - - - )INTROSPECTION"_cs; + + + + + + + + + + + + + +)INTROSPECTION"_cs; constexpr auto kPlayerIntrospectionXML = R"INTROSPECTION( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - )INTROSPECTION"_cs; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)INTROSPECTION"_cs; -auto CreateMetadata(const Media::Player::TrackState &state) { +auto CreateMetadata( + const Media::Player::TrackState &state, + Data::DocumentMedia *trackView) { std::map result; if (!Media::Player::IsStoppedOrStopping(state.state)) { @@ -119,6 +127,25 @@ auto CreateMetadata(const Media::Player::TrackState &state) { } } } + + if (trackView) { + trackView->thumbnailWanted(Data::FileOrigin()); + if (trackView->thumbnail()) { + QByteArray thumbnailData; + QBuffer thumbnailBuffer(&thumbnailData); + trackView->thumbnail()->original().save( + &thumbnailBuffer, + "JPG", + 87); + + result["mpris:artUrl"] = Glib::Variant< + Glib::ustring + >::create("data:image/jpeg;base64," + + thumbnailData + .toBase64() + .toStdString()); + } + } } return result; @@ -237,8 +264,16 @@ void HandleGetProperty( const auto state = Media::Player::instance()->getState( kSongType); + const auto trackView = [&]() -> std::shared_ptr { + const auto audioData = state.id.audio(); + if (audioData && audioData->isSongWithCover()) { + return audioData->activeMediaView(); + } + return nullptr; + }(); + property = base::Platform::MakeGlibVariant( - CreateMetadata(state)); + CreateMetadata(state, trackView.get())); } else if (property_name == "MinimumRate") { property = Glib::Variant::create(1.0); } else if (property_name == "PlaybackStatus") { @@ -349,6 +384,7 @@ public: std::map metadata; Glib::ustring playbackStatus; gint64 position = 0; + std::shared_ptr trackView; rpl::lifetime lifetime; }; @@ -359,7 +395,17 @@ void MPRISSupport::Private::updateTrackState( return; } - const auto currentMetadata = CreateMetadata(state); + const auto audioData = state.id.audio(); + if (audioData && audioData->isSongWithCover()) { + const auto view = audioData->createMediaView(); + if (!trackView || trackView->owner() != view->owner()) { + trackView = view; + } + } else { + trackView = nullptr; + } + + const auto currentMetadata = CreateMetadata(state, trackView.get()); const auto currentPosition = state.position * 1000; const auto currentPlaybackStatus = PlaybackStatus(state.state); @@ -423,6 +469,12 @@ MPRISSupport::MPRISSupport() _private->updateTrackState( Media::Player::instance()->getState(kSongType)); + Core::App().domain().active().session().downloaderTaskFinished( + ) | rpl::start_with_next([=] { + _private->updateTrackState( + Media::Player::instance()->getState(kSongType)); + }, _private->lifetime); + Media::Player::instance()->updatedNotifier( ) | rpl::start_with_next([=]( const Media::Player::TrackState &state) {