audio: Convert the Player into a GObject

And give it "state-changed" and "track-changed" signals.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-08-30 16:27:33 -04:00
parent 596b34eb5a
commit 5c2e4bb016
4 changed files with 32 additions and 11 deletions

View File

@ -5,11 +5,13 @@ from . import nowplaying
from . import seeker from . import seeker
from lib import publisher from lib import publisher
from lib import settings from lib import settings
from gi.repository import GObject
from gi.repository import Gst, GLib from gi.repository import Gst, GLib
import tagdb import tagdb
class Player: class Player(GObject.GObject):
def __init__(self): def __init__(self):
GObject.GObject.__init__(self)
self.video = Gst.ElementFactory.make("fakesink") self.video = Gst.ElementFactory.make("fakesink")
self.playbin = Gst.ElementFactory.make("playbin") self.playbin = Gst.ElementFactory.make("playbin")
self.playbin.set_property("video-sink", self.video) self.playbin.set_property("video-sink", self.video)
@ -35,7 +37,6 @@ class Player:
self.Controls.sizegroup.add_widget(self.Seeker.scale) self.Controls.sizegroup.add_widget(self.Seeker.scale)
GLib.timeout_add(250, self.update_progress) GLib.timeout_add(250, self.update_progress)
self.TrackChanged = publisher.Publisher()
self.track = tagdb.Tracks[settings.get_int("audio.trackid")] self.track = tagdb.Tracks[settings.get_int("audio.trackid")]
self.load_set_state(self.track, Gst.State.PAUSED) self.load_set_state(self.track, Gst.State.PAUSED)
if self.track: if self.track:
@ -59,7 +60,7 @@ class Player:
settings.set("audio.trackid", track.trackid) settings.set("audio.trackid", track.trackid)
uri = track.filepath().absolute().as_uri() uri = track.filepath().absolute().as_uri()
self.playbin.set_property("uri", uri) self.playbin.set_property("uri", uri)
self.TrackChanged.publish(prev, self.track) self.emit("track-changed", prev, self.track)
def load_set_state(self, track, state): def load_set_state(self, track, state):
self.playbin.set_state(Gst.State.READY) self.playbin.set_state(Gst.State.READY)
@ -79,6 +80,7 @@ class Player:
def on_state_changed(self, bus, message): def on_state_changed(self, bus, message):
(old, new, pending) = message.parse_state_changed() (old, new, pending) = message.parse_state_changed()
self.Controls.set_state(new) self.Controls.set_state(new)
self.emit("state-changed", old, new, pending)
def on_tag(self, bus, message): def on_tag(self, bus, message):
taglist = message.parse_tag() taglist = message.parse_tag()
@ -135,3 +137,11 @@ class Player:
def volume_changed(self, *args): def volume_changed(self, *args):
self.playbin.set_property("volume", self.Controls.menu.volume.get_value()) self.playbin.set_property("volume", self.Controls.menu.volume.get_value())
@GObject.Signal(arg_types=(Gst.State, Gst.State, Gst.State))
def state_changed(self, old, new, pending):
pass
@GObject.Signal(arg_types=(tagdb.track.Track, tagdb.track.Track))
def track_changed(self, prev, new):
pass

View File

@ -6,11 +6,14 @@ from . import player
from . import seeker from . import seeker
from lib import publisher from lib import publisher
from lib import settings from lib import settings
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gst from gi.repository import Gst
import pathlib import pathlib
import tagdb import tagdb
import unittest import unittest
main_context = GLib.main_context_default()
test_album = pathlib.Path("./data/Test Album/") test_album = pathlib.Path("./data/Test Album/")
test_track = test_album / "01 - Test Track.ogg" test_track = test_album / "01 - Test Track.ogg"
@ -23,6 +26,7 @@ class TestPlayer(unittest.TestCase):
def setUp(self): def setUp(self):
self.changed = None self.changed = None
self.state_changed = None
settings.reset() settings.reset()
self.library = tagdb.Library.store[test_album] self.library = tagdb.Library.store[test_album]
self.track = [ t for t in self.library.tracks if t.tracknumber == 1 ][0] self.track = [ t for t in self.library.tracks if t.tracknumber == 1 ][0]
@ -30,11 +34,15 @@ class TestPlayer(unittest.TestCase):
def tearDownClass(): def tearDownClass():
tagdb.reset() tagdb.reset()
def on_track_changed(self, prev, new): def on_track_changed(self, player, prev, new):
self.changed = (prev, new) self.changed = (prev, new)
def on_state_changed(self, player, old, new, pending):
self.state_changed = (old, new, pending)
def test_player_init(self): def test_player_init(self):
play = player.Player() play = player.Player()
self.assertIsInstance(play, GObject.GObject)
self.assertIsInstance(play.video, Gst.Element) self.assertIsInstance(play.video, Gst.Element)
self.assertIsInstance(play.playbin, Gst.Element) self.assertIsInstance(play.playbin, Gst.Element)
self.assertIsInstance(play.bus, Gst.Bus) self.assertIsInstance(play.bus, Gst.Bus)
@ -42,7 +50,6 @@ class TestPlayer(unittest.TestCase):
self.assertIsInstance(play.NowPlaying, nowplaying.NowPlaying) self.assertIsInstance(play.NowPlaying, nowplaying.NowPlaying)
self.assertIsInstance(play.Artwork, artwork.Artwork) self.assertIsInstance(play.Artwork, artwork.Artwork)
self.assertIsInstance(play.Seeker, seeker.Seeker) self.assertIsInstance(play.Seeker, seeker.Seeker)
self.assertIsInstance(play.TrackChanged, publisher.Publisher)
self.assertIsNone(play.track) self.assertIsNone(play.track)
self.assertEqual(play.playbin.get_property("video-sink"), play.video) self.assertEqual(play.playbin.get_property("video-sink"), play.video)
@ -51,7 +58,7 @@ class TestPlayer(unittest.TestCase):
def test_player_load_track(self): def test_player_load_track(self):
play = player.Player() play = player.Player()
uri = test_track.absolute().as_uri() uri = test_track.absolute().as_uri()
play.TrackChanged.register(self.on_track_changed) play.connect("track-changed", self.on_track_changed)
self.assertEqual(play.playbin.get_property("uri"), None) self.assertEqual(play.playbin.get_property("uri"), None)
@ -70,6 +77,7 @@ class TestPlayer(unittest.TestCase):
def test_player_play_pause(self): def test_player_play_pause(self):
play = player.Player() play = player.Player()
play.connect("state-changed", self.on_state_changed)
play.load_track(self.track) play.load_track(self.track)
self.assertEqual(play.track, self.track) self.assertEqual(play.track, self.track)
@ -90,9 +98,12 @@ class TestPlayer(unittest.TestCase):
play.pause() play.pause()
self.assertEqual(play.get_state(), Gst.State.PAUSED) self.assertEqual(play.get_state(), Gst.State.PAUSED)
while main_context.iteration(may_block=False): pass
self.assertIsNotNone(self.state_changed)
def test_player_next_previous(self): def test_player_next_previous(self):
play = player.Player() play = player.Player()
play.TrackChanged.register(self.on_track_changed) play.connect("track-changed", self.on_track_changed)
play.next() play.next()
self.assertEqual(play.track.trackid, 0) self.assertEqual(play.track.trackid, 0)

View File

@ -59,9 +59,9 @@ def scroll_to_current(*args):
scroll_to_track(audio.Player.track) scroll_to_track(audio.Player.track)
Model.Controls.jump.connect("clicked", scroll_to_current) Model.Controls.jump.connect("clicked", scroll_to_current)
def on_tracks_changed(prev, new): def on_tracks_changed(player, prev, new):
scroll_to_track(new) scroll_to_track(new)
audio.Player.TrackChanged.register(on_tracks_changed) audio.Player.connect("track-changed", on_tracks_changed)
Box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) Box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)

View File

@ -12,7 +12,7 @@ class TagModel(GObject.GObject, Gio.ListModel):
self.bus = bus.Bus(1) self.bus = bus.Bus(1)
self.items = [ ] self.items = [ ]
self.__set_tag__(tag) self.__set_tag__(tag)
audio.Player.TrackChanged.register(self.on_tracks_changed) audio.Player.connect("track-changed", self.on_tracks_changed)
def __set_tag__(self, tag): def __set_tag__(self, tag):
self.tag = tag self.tag = tag
@ -65,7 +65,7 @@ class TagModel(GObject.GObject, Gio.ListModel):
def track_removed(self, tag, track, pos): def track_removed(self, tag, track, pos):
self.bus.board(self.do_track_removed, tag, track, pos) self.bus.board(self.do_track_removed, tag, track, pos)
def on_tracks_changed(self, prev, new): def on_tracks_changed(self, player, prev, new):
if prev in self.items: if prev in self.items:
self.items_changed(self.items.index(prev), 1, 1) self.items_changed(self.items.index(prev), 1, 1)
if new in self.items: if new in self.items: