[gnome-music/wip/jfelder/async-duration: 26/26] gstplayer: Improve query duration handling




commit ce03e21ac12be26a40de36d57e7c51b8d2c388af
Author: Jean Felder <jfelder src gnome org>
Date:   Sun Mar 21 20:14:32 2021 +0100

    gstplayer: Improve query duration handling
    
    The duration handling logic is changed to now listen to the
    'duration-changed' message to handle duration changes.
    
    However, the duration can only be queried once the pipeline is
    prerolled (it's in the PAUSED or the PLAYING state). If that is not
    the case, the pipeline will receive an 'async-done' message once it's
    prerolled and the duration needs to be queried.
    
    With this new logic it's possible to remove the timeout to query
    duration at the start of the stream: if the pipeline is already
    prerolled, the duaration query will succeed. If not, the duration will
    be queried once an 'async-done' or 'duration-changed' message will be
    received.

 gnomemusic/gstplayer.py | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)
---
diff --git a/gnomemusic/gstplayer.py b/gnomemusic/gstplayer.py
index a4b72cc1a..edf3dbb9f 100644
--- a/gnomemusic/gstplayer.py
+++ b/gnomemusic/gstplayer.py
@@ -31,7 +31,7 @@ from gettext import gettext as _, ngettext
 import gi
 gi.require_version('Gst', '1.0')
 gi.require_version('GstPbutils', '1.0')
-from gi.repository import GLib, Gtk, Gio, GObject, Gst, GstPbutils
+from gi.repository import Gtk, Gio, GObject, Gst, GstPbutils
 
 if typing.TYPE_CHECKING:
     from gnomemusic.application import Application
@@ -70,6 +70,7 @@ class GstPlayer(GObject.GObject):
 
         self._application = application
         self._duration = -1.
+        self._known_duration = False
         self._log = application.props.log
         self._seek = False
         self._tick = 0
@@ -91,6 +92,8 @@ class GstPlayer(GObject.GObject):
             None, self._settings.get_value('replaygain'))
 
         self._bus.connect('message::async-done', self._on_async_done)
+        self._bus.connect(
+            "message::duration-changed", self._on_duration_changed)
         self._bus.connect('message::error', self._on_bus_error)
         self._bus.connect('message::element', self._on_bus_element)
         self._bus.connect('message::eos', self._on_bus_eos)
@@ -140,12 +143,19 @@ class GstPlayer(GObject.GObject):
             self._seek = False
             self.emit("seek-finished")
 
+        if not self._known_duration:
+            self._query_duration()
+
+    def _on_duration_changed(self, bus, message):
+        self._query_duration()
+
     def _query_duration(self):
-        success, duration = self._player.query_duration(
+        self._known_duration, duration = self._player.query_duration(
             Gst.Format.TIME)
 
-        if success:
+        if self._known_duration:
             self.props.duration = duration / Gst.SECOND
+            self._log.debug("duration changed: {}".format(self.props.duration))
         else:
             self.props.duration = duration
 
@@ -177,14 +187,9 @@ class GstPlayer(GObject.GObject):
             self._missing_plugin_messages.append(message)
 
     def _on_bus_stream_start(self, bus, message):
-        def delayed_query():
-            self._query_duration()
-            self._tick = 0
-            self.emit("stream-start")
-
-        # Delay the signalling slightly or the new duration will not
-        # have been set yet.
-        GLib.timeout_add(1, delayed_query)
+        self._query_duration()
+        self._tick = 0
+        self.emit("stream-start")
 
     def _on_state_changed(self, bus, message):
         if message.src != self._player:


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