[gnome-music/wip/jfelder/mpris-fix-seek: 1/2] mpris: Correctly handle MPRIS position unit



commit 05291f95c99af6b4cb19d9b963bea8c492a453d9
Author: Jean Felder <jfelder src gnome org>
Date:   Tue Sep 25 10:34:29 2018 +0200

    mpris: Correctly handle MPRIS position unit
    
    MPRIS position unit is in microseconds while GstPlayer position and
    duration unit is seconds.
    Correctly handle the conversion between the two objects.
    
    Use the following syntax:
     * position means an absolute position
     * offset means a position relative to the current one
     * msecond means a position in microseconds
     * second means a position in seconds
    
    Closes: #227

 gnomemusic/mpris.py  | 38 +++++++++++++++++++++++++++++---------
 gnomemusic/player.py | 31 +++++++++++++++++++------------
 2 files changed, 48 insertions(+), 21 deletions(-)
---
diff --git a/gnomemusic/mpris.py b/gnomemusic/mpris.py
index 078e2324..2e22a03a 100644
--- a/gnomemusic/mpris.py
+++ b/gnomemusic/mpris.py
@@ -471,8 +471,8 @@ class MediaPlayer2Service(Server):
         self.player.play()
 
     @log
-    def _on_seeked(self, player, position, data=None):
-        self.Seeked(position)
+    def _on_seeked(self, player, position_second):
+        self.Seeked(position_second * 1e6)
 
     @log
     def _on_playlist_changed(self, player, data=None):
@@ -550,23 +550,42 @@ class MediaPlayer2Service(Server):
             else:
                 self.first_song_handler = model.connect('row-inserted', self._play_first_song)
 
-    def Seek(self, offset):
-        self.player.set_position(offset, True, True)
+    def Seek(self, offset_msecond):
+        """Seek forward in the current track.
 
-    def SetPosition(self, track_id, position):
+        Seek is relative to the current player position.
+        If the value passed in would mean seeking beyond the end of the track,
+        acts like a call to Next.
+        :param float offset_msecond: number of microseconds
+        """
+        current_position_msecond = self.player.get_position() * 1e6
+        new_position_msecond = current_position_msecond + offset_msecond
+        self.player.set_position(new_position_msecond, True)
+
+    def SetPosition(self, track_id, position_msecond):
+        """Set the current track position in microseconds.
+
+        :param str track_id: The currently playing track's identifier
+        :param float position_msecond: new position in microseconds
+        """
         if track_id != self._get_metadata().get('mpris:trackid').get_string():
             return
-        self.player.set_position(position)
+        self.player.set_position(position_msecond)
 
     def OpenUri(self, uri):
         pass
 
-    def Seeked(self, position):
+    def Seeked(self, position_msecond):
+        """Indicate that the track position has changed.
+
+        :param position_msecond: new position in microseconds.
+        """
+        variant = GLib.Variant.new_tuple(GLib.Variant('x', position_msecond))
         self.con.emit_signal(None,
                              '/org/mpris/MediaPlayer2',
                              MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE,
                              'Seeked',
-                             GLib.Variant.new_tuple(GLib.Variant('x', position)))
+                             variant)
 
     def GetTracksMetadata(self, track_ids):
         metadata = []
@@ -661,6 +680,7 @@ class MediaPlayer2Service(Server):
                 ]),
             }
         elif interface_name == MediaPlayer2Service.MEDIA_PLAYER2_PLAYER_IFACE:
+            position_second = self.player.get_position()
             return {
                 'PlaybackStatus': GLib.Variant('s', self._get_playback_status()),
                 'LoopStatus': GLib.Variant('s', self._get_loop_status()),
@@ -668,7 +688,7 @@ class MediaPlayer2Service(Server):
                 'Shuffle': GLib.Variant('b', self.player.props.repeat_mode == RepeatMode.SHUFFLE),
                 'Metadata': GLib.Variant('a{sv}', self._get_metadata()),
                 'Volume': GLib.Variant('d', self.player.get_volume()),
-                'Position': GLib.Variant('x', self.player.get_position()),
+                'Position': GLib.Variant('x', position_second * 1e6),
                 'MinimumRate': GLib.Variant('d', 1.0),
                 'MaximumRate': GLib.Variant('d', 1.0),
                 'CanGoNext': GLib.Variant('b', self.player.props.has_next),
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 1da1f16b..f985f9cf 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -824,24 +824,31 @@ class Player(GObject.GObject):
 
     @log
     def get_position(self):
+        """Get player position.
+
+        Player position in seconds.
+        :returns: position
+        :rtype: float
+        """
         return self._player.position
 
     # TODO: used by MPRIS
     @log
-    def set_position(self, offset, start_if_ne=False, next_on_overflow=False):
-        if offset < 0:
-            if start_if_ne:
-                offset = 0
-            else:
-                return
+    def set_position(self, position_msecond, next_on_overflow=False):
+        """Change GstPlayer position.
 
-        duration = self._player.duration
-        if duration is None:
-            return
+        If requested position is negative, set it to zero.
+        :param position_msecond: requested position in microsecond
+        :param next_on_overflow: next song if position is greater than duration
+        """
+        if position_msecond < 0.0:
+            position_msecond = 0.0
+
+        duration_second = self._player.duration
+        position_second = position_msecond / 1e6
 
-        if duration >= offset * 1000:
-            self._player.seek(offset * 1000)
-            self.emit('seeked', offset)
+        if position_second <= duration_second:
+            self._player.seek(position_second)
         elif next_on_overflow:
             self.next()
 


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