From 4cdf4c528a0d796b4d58d020d567f346ad05f5cc Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 9 Dec 2021 17:22:25 -0500 Subject: [PATCH] audio: Implement our own about-to-finish handling The playbin's about-to-finish signal triggers in a different thread, which Gtk is very much not happy about, and often results in both the about-to-finish and eos handlers getting called (and therefore multiple tracks getting picked from the queue). Fix this by checking how much time is left during the regular position changed timeout function and triggering about-to-finish manually Signed-off-by: Anna Schumaker --- audio/bass.py | 16 +++++++--------- audio/test_bass.py | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/audio/bass.py b/audio/bass.py index 5d6e4e6..eec843e 100644 --- a/audio/bass.py +++ b/audio/bass.py @@ -11,6 +11,8 @@ Gst.init(sys.argv) from . import replaygain +TIMEOUT = 100 + class BassPlayer(GObject.GObject): def __init__(self): @@ -22,7 +24,6 @@ class BassPlayer(GObject.GObject): self.video = Gst.ElementFactory.make("fakesink") self.playbin = Gst.ElementFactory.make("playbin") - self.playbin.connect("about-to-finish", self.__about_to_finish__) self.playbin.set_property("audio-sink", self.audio) self.playbin.set_property("video-sink", self.video) self.playbin.set_property("volume", lib.settings.get_float("audio.volume")) @@ -38,9 +39,6 @@ class BassPlayer(GObject.GObject): self.timeout = None - def __about_to_finish__(self, playbin): - self.emit("about-to-finish") - def __eos__(self, bus, message): self.emit("eos") @@ -110,9 +108,6 @@ class BassPlayer(GObject.GObject): self.playbin.set_property("volume", vol) lib.settings.set("audio.volume", vol) - def about_to_finish(self, playbin): - pass - def state_changed(self, bus, message): if message.src == self.playbin: (old, new, pending) = message.parse_state_changed() @@ -152,7 +147,7 @@ class BassPlayer(GObject.GObject): @GObject.Signal def playback_start(self): if not self.timeout: - self.timeout = GLib.timeout_add(200, self.timeout_function) + self.timeout = GLib.timeout_add(TIMEOUT, self.timeout_function) @GObject.Signal def playback_paused(self): @@ -162,4 +157,7 @@ class BassPlayer(GObject.GObject): @GObject.Signal def position_changed(self): - pass + remaining = self.duration - self.position + if remaining < 2 * Gst.SECOND: + if remaining + (TIMEOUT * Gst.MSECOND) >= 2 * Gst.SECOND: + self.emit("about-to-finish") diff --git a/audio/test_bass.py b/audio/test_bass.py index 74f69b1..328d3b9 100644 --- a/audio/test_bass.py +++ b/audio/test_bass.py @@ -32,7 +32,7 @@ class TestBassPlayer(unittest.TestCase): self.assertEqual(base.playbin.get_property("video-sink"), base.video) self.assertEqual(base.playbin.get_state(Gst.CLOCK_TIME_NONE)[1], Gst.State.READY) - self.assertIsNone(base.timeout, 0) + self.assertIsNone(base.timeout) def test_bass_player_bus(self): base = bass.BassPlayer()