audio: Add ReplayGain support to the Gst.Playbin

And add functions for setting and quering the state.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2022-06-14 16:35:03 -04:00
parent d134b303ab
commit 93dc476706
2 changed files with 38 additions and 0 deletions

View File

@ -2,6 +2,7 @@
"""A custom GObject managing a GStreamer playbin."""
from gi.repository import GObject
from gi.repository import Gst
from . import replaygain
class Player(GObject.GObject):
@ -12,17 +13,29 @@ class Player(GObject.GObject):
def __init__(self):
"""Initialize the audio Player."""
super().__init__()
self._replaygain = replaygain.Filter()
self._playbin = Gst.ElementFactory.make("playbin")
self._playbin.set_property("audio-filter", self._replaygain)
self._playbin.set_property("video-sink",
Gst.ElementFactory.make("fakesink"))
self._playbin.set_state(Gst.State.READY)
self.bind_property("volume", self._playbin, "volume")
def get_replaygain(self) -> tuple[bool, str | None]:
"""Get the current ReplayGain mode."""
mode = self._replaygain.mode
return (False, None) if mode == "disabled" else (True, mode)
def get_state(self) -> Gst.State:
"""Get the current state of the Player."""
return self._playbin.get_state(Gst.CLOCK_TIME_NONE).state
def set_replaygain(self, enabled: bool, mode: str) -> None:
"""Set the ReplayGain mode."""
self._replaygain.mode = mode if enabled else "disabled"
def shutdown(self) -> None:
"""Shut down the player."""
self._playbin.set_state(Gst.State.NULL)

View File

@ -1,6 +1,8 @@
# Copyright 2022 (c) Anna Schumaker.
"""Tests our GObject audio player wrapping a GStreamer Playbin element."""
import io
import unittest
import unittest.mock
import emmental.audio
from gi.repository import GObject
from gi.repository import Gst
@ -36,6 +38,29 @@ class TestAudio(unittest.TestCase):
self.assertEqual(self.player.volume, 0.5)
self.assertEqual(self.player._playbin.get_property("volume"), 0.5)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_replaygain(self, mock_stdout: io.StringIO):
"""Test that ReplayGain functions work as expected."""
self.assertIsInstance(self.player._replaygain,
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.player.set_replaygain(True, "album")
self.assertEqual(self.player._replaygain.mode, "album")
self.assertEqual(self.player.get_replaygain(), (True, "album"))
self.assertRegex(mock_stdout.getvalue(),
r"audio: setting ReplayGain mode to 'album'")
self.player.set_replaygain(False, "track")
self.assertEqual(self.player._replaygain.mode, "disabled")
self.assertEqual(self.player.get_replaygain(), (False, None))
self.assertRegex(mock_stdout.getvalue(),
r"audio: setting ReplayGain mode to 'disabled'")
def test_shutdown(self):
"""Test that the shutdown function works as expected."""
self.player.shutdown()