Anna Schumaker
4cdf4c528a
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>
138 lines
5.4 KiB
Python
138 lines
5.4 KiB
Python
# Copyright 2021 (c) Anna Schumaker.
|
|
import lib
|
|
import pathlib
|
|
import time
|
|
import unittest
|
|
from gi.repository import GObject
|
|
from gi.repository import GLib
|
|
from gi.repository import Gst
|
|
from . import bass
|
|
from . import replaygain
|
|
|
|
main_context = GLib.main_context_default()
|
|
test_album = pathlib.Path("./data/Test Album/")
|
|
test_track = test_album / "01 - Test Track.ogg"
|
|
test_uri = test_track.absolute().as_uri()
|
|
|
|
class TestBassPlayer(unittest.TestCase):
|
|
def setUp(self):
|
|
self.duration_changed = None
|
|
|
|
def on_duration_changed(self, player): self.duration_changed = player.duration
|
|
def on_playback_start(self, player): self.playing = True
|
|
def on_playback_paused(self, player): self.playing = False
|
|
|
|
def test_bass_player_init(self):
|
|
base = bass.BassPlayer()
|
|
self.assertIsInstance(base, GObject.GObject)
|
|
self.assertIsInstance(base.audio, replaygain.ReplayGainSink)
|
|
self.assertIsInstance(base.video, Gst.Element)
|
|
self.assertIsInstance(base.playbin, Gst.Element)
|
|
self.assertEqual(base.playbin.get_property("audio-sink"), base.audio)
|
|
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)
|
|
|
|
def test_bass_player_bus(self):
|
|
base = bass.BassPlayer()
|
|
self.assertIsInstance(base.bus, Gst.Bus)
|
|
|
|
def test_bass_player_duration(self):
|
|
base = bass.BassPlayer()
|
|
base.connect("duration-changed", self.on_duration_changed)
|
|
self.assertEqual(base.get_property("duration"), 0)
|
|
|
|
base.set_property("uri", test_uri)
|
|
base.set_property("playing", False)
|
|
|
|
iterations = 0
|
|
while self.duration_changed == None:
|
|
main_context.iteration(may_block=False)
|
|
if (iterations := iterations +1) == 100000:
|
|
break
|
|
|
|
self.assertEqual(base.get_property("duration"), 10 * Gst.SECOND)
|
|
self.assertEqual(self.duration_changed, 10 * Gst.SECOND)
|
|
|
|
def test_bass_player_playing(self):
|
|
base = bass.BassPlayer()
|
|
base.connect("playback-start", self.on_playback_start)
|
|
base.connect("playback-paused", self.on_playback_paused)
|
|
base.set_property("uri", test_uri)
|
|
self.assertFalse(base.get_property("playing"))
|
|
|
|
base.set_property("playing", True)
|
|
(ret, state, pending) = base.playbin.get_state(Gst.CLOCK_TIME_NONE)
|
|
self.assertEqual(state, Gst.State.PLAYING)
|
|
self.assertTrue(base.get_property("playing"))
|
|
while main_context.iteration(may_block=False): pass
|
|
self.assertIsNotNone(base.timeout)
|
|
|
|
base.set_property("playing", False)
|
|
(ret, state, pending) = base.playbin.get_state(Gst.CLOCK_TIME_NONE)
|
|
self.assertEqual(state, Gst.State.PAUSED)
|
|
self.assertFalse(base.get_property("playing"))
|
|
while main_context.iteration(may_block=False): pass
|
|
self.assertIsNone(base.timeout)
|
|
|
|
def test_basic_player_position(self):
|
|
base = bass.BassPlayer()
|
|
self.assertEqual(base.get_property("position"), 0)
|
|
|
|
base.set_property("uri", test_uri)
|
|
base.set_property("playing", False)
|
|
time.sleep(0.1)
|
|
while main_context.iteration(may_block=False): time.sleep(0.005)
|
|
|
|
base.set_property("position", 5 * Gst.SECOND)
|
|
time.sleep(0.2)
|
|
while main_context.iteration(may_block=False): time.sleep(0.005)
|
|
self.assertGreater(base.get_property("position"), 0)
|
|
|
|
def test_bass_player_replaygain(self):
|
|
lib.settings.reset()
|
|
base = bass.BassPlayer()
|
|
self.assertEqual(lib.settings.get("audio.replaygain"), "disabled")
|
|
self.assertEqual(base.get_property("replaygain"), "disabled")
|
|
|
|
base.set_property("replaygain", "track")
|
|
self.assertEqual(base.audio.get_property("mode"), "track")
|
|
self.assertEqual(base.get_property("replaygain"), "track")
|
|
self.assertEqual(lib.settings.get("audio.replaygain"), "track")
|
|
|
|
base.set_property("replaygain", "disabled")
|
|
self.assertEqual(base.audio.get_property("mode"), "disabled")
|
|
self.assertEqual(base.get_property("replaygain"), "disabled")
|
|
self.assertEqual(lib.settings.get("audio.replaygain"), "disabled")
|
|
|
|
base.set_property("replaygain", "album")
|
|
self.assertEqual(base.audio.get_property("mode"), "album")
|
|
self.assertEqual(base.get_property("replaygain"), "album")
|
|
self.assertEqual(lib.settings.get("audio.replaygain"), "album")
|
|
|
|
def test_bass_player_uri(self):
|
|
base = bass.BassPlayer()
|
|
|
|
self.assertIsNone(base.get_property("uri"))
|
|
base.set_property("uri", test_uri)
|
|
self.assertEqual(base.get_property("uri"), test_uri)
|
|
|
|
base.playbin.set_state(Gst.State.PAUSED)
|
|
base.set_property("uri", None)
|
|
self.assertEqual(base.playbin.get_state(Gst.CLOCK_TIME_NONE)[1],
|
|
Gst.State.READY)
|
|
|
|
def test_bass_player_volume(self):
|
|
lib.settings.reset()
|
|
base = bass.BassPlayer()
|
|
|
|
self.assertEqual(lib.settings.get_float("audio.volume"), 1.0)
|
|
self.assertEqual(base.get_property("volume"), 1.0)
|
|
base.set_property("volume", 0.5)
|
|
self.assertEqual(base.get_property("volume"), 0.5)
|
|
self.assertEqual(lib.settings.get_float("audio.volume"), 0.5)
|
|
|
|
base2 = bass.BassPlayer()
|
|
self.assertEqual(base2.get_property("volume"), 0.5)
|