[gnome-music/wip/jfelder/mpris-synchronise-coverart] mpris: Synchronize metadata emission on song change



commit 8b1f066d6778575a5541a9dbcd6fa874f80bc743
Author: Jean Felder <jean@small-ubu>
Date:   Mon Mar 25 23:53:52 2019 +0100

    mpris: Synchronize metadata emission on song change
    
    When a song changes, two signals are emitted: "current-song-changed"
    and "thumbnail-updated". Most of the time, "current-song-changed" will
    arrive first. So, the metadata property will be sent with an empty
    artUrl. Then, the thumbnail_updated method will send again the
    metadata with the correct artUrl. By adding a timeout, it waits for
    the arrival of the second signal and prevents to send two different signals.
    
    Related: #43, #101

 gnomemusic/mpris.py | 53 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 17 deletions(-)
---
diff --git a/gnomemusic/mpris.py b/gnomemusic/mpris.py
index b74c4c53..8d6c3a6f 100644
--- a/gnomemusic/mpris.py
+++ b/gnomemusic/mpris.py
@@ -257,6 +257,8 @@ class MediaPlayer2Service(Server):
         self._player_previous_type = None
         self._path_list = []
         self._metadata_list = []
+        self._metadata_timeout = None
+        self._current_thumbnail = None
         self._previous_playback_status = "Stopped"
 
     @log
@@ -436,28 +438,45 @@ class MediaPlayer2Service(Server):
 
     @log
     def _on_current_song_changed(self, player):
+        def send_signal():
+            has_next = self.player.props.has_next
+            has_previous = self.player.props.has_previous
+            self.PropertiesChanged(
+                MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE,
+                {
+                    'CanGoNext': GLib.Variant('b', has_next),
+                    'CanGoPrevious': GLib.Variant('b', has_previous),
+                    'CanPlay': GLib.Variant('b', True),
+                    'CanPause': GLib.Variant('b', True),
+                    'Metadata': GLib.Variant('a{sv}', self._get_metadata()),
+                },
+                [])
+            self._metadata_timeout = None
+            current_song = self.player.props.current_song
+            self._current_thumbnail = current_song.get_thumbnail()
+
         self._update_songs_list()
 
-        has_next = self.player.props.has_next
-        has_previous = self.player.props.has_previous
-        self.PropertiesChanged(MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE,
-                               {
-                                   'Metadata': GLib.Variant('a{sv}', self._get_metadata()),
-                                   'CanGoNext': GLib.Variant('b', has_next),
-                                   'CanGoPrevious': GLib.Variant(
-                                       'b', has_previous),
-                                   'CanPlay': GLib.Variant('b', True),
-                                   'CanPause': GLib.Variant('b', True),
-                               },
-                               [])
+        # When a song changes, two signals are emitted:
+        # "current-song-changed" and "thumbnail-updated". Most of the
+        # time, "current-song-changed" will arrive first. So, the
+        # metadata property will be sent with an empty artUrl. Then, the
+        # thumbnail_updated method will send again the metadata with the
+        # correct artUrl. By adding a timeout, it waits for the arrival
+        # of the second signal and prevents to send two different
+        # signals.
+        self._metadata_timeout = GLib.timeout_add(250, send_signal)
 
     @log
     def _on_thumbnail_updated(self, player, data=None):
-        self.PropertiesChanged(MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE,
-                               {
-                                   'Metadata': GLib.Variant('a{sv}', self._get_metadata()),
-                               },
-                               [])
+        new_thumbnail = self.player.props.current_song.get_thumbnail()
+        if (not self._metadata_timeout
+                and new_thumbnail != self._current_thumbnail):
+            metadata = GLib.Variant('a{sv}', self._get_metadata())
+            self.PropertiesChanged(
+                MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE,
+                {'Metadata': metadata, }, [])
+            self._current_thumbnail = new_thumbnail
 
     @log
     def _on_player_state_changed(self, klass, args):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]