audio: Replace the playbin audio-filter with the new filter
And wire up the bg-enabled and bg-volume properties from the header to the playbin properties with the same name. Implements: #50 ("Background Music Mode") Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
84fbd94aa1
commit
8afd1a6240
|
@ -127,7 +127,8 @@ class Application(Adw.Application):
|
||||||
def build_header(self) -> header.Header:
|
def build_header(self) -> header.Header:
|
||||||
"""Build a new header instance."""
|
"""Build a new header instance."""
|
||||||
hdr = header.Header(sql=self.db, title=VERSION_STRING)
|
hdr = header.Header(sql=self.db, title=VERSION_STRING)
|
||||||
hdr.bind_property("volume", self.player, "volume")
|
for prop in ["bg-enabled", "bg-volume", "volume"]:
|
||||||
|
hdr.bind_property(prop, self.player, prop)
|
||||||
for (setting, property) in [("audio.volume", "volume"),
|
for (setting, property) in [("audio.volume", "volume"),
|
||||||
("audio.background.enabled", "bg-enabled"),
|
("audio.background.enabled", "bg-enabled"),
|
||||||
("audio.background.volume", "bg-volume"),
|
("audio.background.volume", "bg-volume"),
|
||||||
|
|
|
@ -4,7 +4,7 @@ import pathlib
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
from gi.repository import Gst
|
from gi.repository import Gst
|
||||||
from . import replaygain
|
from . import filter
|
||||||
from .. import path
|
from .. import path
|
||||||
from .. import tmpdir
|
from .. import tmpdir
|
||||||
|
|
||||||
|
@ -35,16 +35,18 @@ class Player(GObject.GObject):
|
||||||
playtime = GObject.Property(type=float)
|
playtime = GObject.Property(type=float)
|
||||||
savedtime = GObject.Property(type=float)
|
savedtime = GObject.Property(type=float)
|
||||||
|
|
||||||
|
bg_enabled = GObject.Property(type=bool, default=False)
|
||||||
|
bg_volume = GObject.Property(type=float, default=0.5)
|
||||||
pause_on_load = GObject.Property(type=bool, default=False)
|
pause_on_load = GObject.Property(type=bool, default=False)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize the audio Player."""
|
"""Initialize the audio Player."""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._replaygain = replaygain.Filter()
|
self._filter = filter.Filter()
|
||||||
self._timeout = None
|
self._timeout = None
|
||||||
|
|
||||||
self._playbin = Gst.ElementFactory.make("playbin")
|
self._playbin = Gst.ElementFactory.make("playbin")
|
||||||
self._playbin.set_property("audio-filter", self._replaygain)
|
self._playbin.set_property("audio-filter", self._filter)
|
||||||
self._playbin.set_property("video-sink",
|
self._playbin.set_property("video-sink",
|
||||||
Gst.ElementFactory.make("fakesink"))
|
Gst.ElementFactory.make("fakesink"))
|
||||||
self._playbin.set_state(Gst.State.READY)
|
self._playbin.set_state(Gst.State.READY)
|
||||||
|
@ -58,6 +60,8 @@ class Player(GObject.GObject):
|
||||||
bus.connect("message::tag", self.__msg_tags)
|
bus.connect("message::tag", self.__msg_tags)
|
||||||
|
|
||||||
self.bind_property("volume", self._playbin, "volume")
|
self.bind_property("volume", self._playbin, "volume")
|
||||||
|
self.bind_property("bg-enabled", self._filter, "bg-enabled")
|
||||||
|
self.bind_property("bg-volume", self._filter, "bg-volume")
|
||||||
|
|
||||||
self.connect("notify::file", self.__notify_file)
|
self.connect("notify::file", self.__notify_file)
|
||||||
|
|
||||||
|
@ -163,7 +167,7 @@ class Player(GObject.GObject):
|
||||||
|
|
||||||
def get_replaygain(self) -> tuple[bool, str | None]:
|
def get_replaygain(self) -> tuple[bool, str | None]:
|
||||||
"""Get the current ReplayGain mode."""
|
"""Get the current ReplayGain mode."""
|
||||||
mode = self._replaygain.mode
|
mode = self._filter.rg_mode
|
||||||
return (False, None) if mode == "disabled" else (True, mode)
|
return (False, None) if mode == "disabled" else (True, mode)
|
||||||
|
|
||||||
def get_state(self) -> Gst.State:
|
def get_state(self) -> Gst.State:
|
||||||
|
@ -191,7 +195,7 @@ class Player(GObject.GObject):
|
||||||
|
|
||||||
def set_replaygain(self, enabled: bool, mode: str) -> None:
|
def set_replaygain(self, enabled: bool, mode: str) -> None:
|
||||||
"""Set the ReplayGain mode."""
|
"""Set the ReplayGain mode."""
|
||||||
self._replaygain.mode = mode if enabled else "disabled"
|
self._filter.rg_mode = mode if enabled else "disabled"
|
||||||
|
|
||||||
def set_state_sync(self, state: Gst.State) -> None:
|
def set_state_sync(self, state: Gst.State) -> None:
|
||||||
"""Set the state of the playbin, and wait for it to change."""
|
"""Set the state of the playbin, and wait for it to change."""
|
||||||
|
|
|
@ -53,6 +53,27 @@ class TestAudio(unittest.TestCase):
|
||||||
self.assertRegex(self.player._playbin.get_property("video-sink").name,
|
self.assertRegex(self.player._playbin.get_property("video-sink").name,
|
||||||
r"fakesink\d+")
|
r"fakesink\d+")
|
||||||
|
|
||||||
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
|
def test_filter(self, mock_stdout: io.StringIO):
|
||||||
|
"""Test the filter element added to the playbin."""
|
||||||
|
self.assertIsInstance(self.player._filter,
|
||||||
|
emmental.audio.filter.Filter)
|
||||||
|
self.assertEqual(self.player._playbin.get_property("audio-filter"),
|
||||||
|
self.player._filter)
|
||||||
|
|
||||||
|
self.assertFalse(self.player.bg_enabled)
|
||||||
|
self.assertEqual(self.player.bg_volume, 0.5)
|
||||||
|
|
||||||
|
self.player.bg_enabled = True
|
||||||
|
self.player.bg_volume = 0.75
|
||||||
|
self.assertTrue(self.player._filter.bg_enabled)
|
||||||
|
self.assertEqual(self.player._filter.bg_volume, 0.75)
|
||||||
|
|
||||||
|
self.player.bg_enabled = False
|
||||||
|
self.player.bg_volume = 0.5
|
||||||
|
self.assertFalse(self.player._filter.bg_enabled)
|
||||||
|
self.assertEqual(self.player.bg_volume, 0.5)
|
||||||
|
|
||||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
def test_eos(self, mock_stdout: io.StringIO):
|
def test_eos(self, mock_stdout: io.StringIO):
|
||||||
"""Test handling an EOS message."""
|
"""Test handling an EOS message."""
|
||||||
|
@ -297,22 +318,17 @@ class TestAudio(unittest.TestCase):
|
||||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
def test_replaygain(self, mock_stdout: io.StringIO):
|
def test_replaygain(self, mock_stdout: io.StringIO):
|
||||||
"""Test that ReplayGain functions work as expected."""
|
"""Test that ReplayGain functions work as expected."""
|
||||||
self.assertIsInstance(self.player._replaygain,
|
self.assertEqual(self.player._filter.rg_mode, "disabled")
|
||||||
emmental.audio.replaygain.Filter)
|
|
||||||
self.assertEqual(self.player._playbin.get_property("audio-filter"),
|
|
||||||
self.player._replaygain)
|
|
||||||
|
|
||||||
self.assertEqual(self.player._replaygain.mode, "disabled")
|
|
||||||
self.assertEqual(self.player.get_replaygain(), (False, None))
|
self.assertEqual(self.player.get_replaygain(), (False, None))
|
||||||
|
|
||||||
self.player.set_replaygain(True, "album")
|
self.player.set_replaygain(True, "album")
|
||||||
self.assertEqual(self.player._replaygain.mode, "album")
|
self.assertEqual(self.player._filter.rg_mode, "album")
|
||||||
self.assertEqual(self.player.get_replaygain(), (True, "album"))
|
self.assertEqual(self.player.get_replaygain(), (True, "album"))
|
||||||
self.assertRegex(mock_stdout.getvalue(),
|
self.assertRegex(mock_stdout.getvalue(),
|
||||||
r"audio: setting ReplayGain mode to 'album'")
|
r"audio: setting ReplayGain mode to 'album'")
|
||||||
|
|
||||||
self.player.set_replaygain(False, "track")
|
self.player.set_replaygain(False, "track")
|
||||||
self.assertEqual(self.player._replaygain.mode, "disabled")
|
self.assertEqual(self.player._filter.rg_mode, "disabled")
|
||||||
self.assertEqual(self.player.get_replaygain(), (False, None))
|
self.assertEqual(self.player.get_replaygain(), (False, None))
|
||||||
self.assertRegex(mock_stdout.getvalue(),
|
self.assertRegex(mock_stdout.getvalue(),
|
||||||
r"audio: setting ReplayGain mode to 'disabled'")
|
r"audio: setting ReplayGain mode to 'disabled'")
|
||||||
|
|
|
@ -220,3 +220,18 @@ class TestEmmental(unittest.TestCase):
|
||||||
self.assertEqual(player.get_replaygain(), (True, "track"))
|
self.assertEqual(player.get_replaygain(), (True, "track"))
|
||||||
win.header.rg_mode = "album"
|
win.header.rg_mode = "album"
|
||||||
self.assertEqual(player.get_replaygain(), (True, "album"))
|
self.assertEqual(player.get_replaygain(), (True, "album"))
|
||||||
|
|
||||||
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
|
def test_background_mode(self, mock_stdout: io.StringIO):
|
||||||
|
"""Test setting background mode."""
|
||||||
|
self.application.db = emmental.db.Connection()
|
||||||
|
self.application.factory = emmental.playlist.Factory(
|
||||||
|
self.application.db)
|
||||||
|
self.application.player = emmental.audio.Player()
|
||||||
|
win = self.application.build_window()
|
||||||
|
player = self.application.player
|
||||||
|
|
||||||
|
win.header.bg_enabled = True
|
||||||
|
win.header.bg_volume = 0.5
|
||||||
|
self.assertTrue(player.bg_enabled)
|
||||||
|
self.assertEqual(player.bg_volume, 0.5)
|
||||||
|
|
Loading…
Reference in New Issue