emmental/audio/test_bass.py
Anna Schumaker 4cdf4c528a 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>
2021-12-09 17:51:02 -05:00

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)