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 <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
8f26cf9fee
commit
4cdf4c528a
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue