From 629bc782fc1607b4d32af1d872b9a01749e9e532 Mon Sep 17 00:00:00 2001 From: Erica Z Date: Sun, 13 Oct 2024 09:56:28 +0000 Subject: [PATCH] playbin refactor --- src/playbin.vala | 134 +++++++++++++++++++++++---------------------- src/ui/window.vala | 4 +- 2 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/playbin.vala b/src/playbin.vala index 8d47c3f..ed43593 100644 --- a/src/playbin.vala +++ b/src/playbin.vala @@ -16,17 +16,17 @@ class Playbin : Object { } public bool mute { - get { return playbin.mute; } - set { playbin.mute = value; } + get { return this.playbin.mute; } + set { this.playbin.mute = value; } } - public signal void set_position (int64 position); + public int64 position { get; private set; } public int64 duration { get; private set; } public signal void stream_started (); public signal void stream_over (); - private void on_source_setup (Gst.Element playbin, dynamic Gst.Element source) { + private void source_setup (Gst.Element playbin, dynamic Gst.Element source) { source.user_agent = "audrey/linux"; } @@ -34,79 +34,85 @@ class Playbin : Object { this.playbin = Gst.ElementFactory.make ("playbin3", null); assert (this.playbin != null); - this.playbin.source_setup.connect (this.on_source_setup); + this.playbin.source_setup.connect (this.source_setup); + this.playbin.about_to_finish.connect (this.about_to_finish); // regularly update position Timeout.add (500, () => { int64 new_position; if (this.playbin.query_position (Gst.Format.TIME, out new_position)) { - this.set_position (new_position < this.duration ? new_position : this.duration); + this.position = new_position < this.duration ? new_position : this.duration; + } else { + this.position = 0; } // keep rerunning return true; }); - this.playbin.get_bus ().add_watch (Priority.DEFAULT, (bus, message) => { - // message.type actually seems to be flags - if (Gst.MessageType.ERROR in message.type) { - Error err; - string? debug; - message.parse_error (out err, out debug); - warning ("gst playbin bus error: %s", err.message); - } + var bus = this.playbin.get_bus (); + bus.add_signal_watch (); - if (Gst.MessageType.ASYNC_DONE in message.type) { - assert (this.async_done_callback != null); - var cb = (owned) this.async_done_callback; - assert (this.async_done_callback == null); // sanity check - cb (); - } - - if (Gst.MessageType.STREAM_START in message.type) { - int64 new_duration; - assert (this.playbin.query_duration (Gst.Format.TIME, out new_duration)); - this.duration = new_duration; - - string? next_uri = null; - - this.next_uri_lock.lock (); - next_uri = this.next_uri; - - if (next_uri != (string) this.playbin.current_uri) { - this.next_uri_lock.unlock (); - // WHOOPS! didn't actually switch to the track the play queue wanted - // we can still fix this though - assert (next_uri != null); - this.playbin.set_state (Gst.State.READY); - this.playbin.uri = next_uri; - this.playbin.set_state (Gst.State.PLAYING); - // no one will ever know - } else { - this.next_uri = null; - this.next_uri_lock.unlock (); - - this.stream_started (); - } - } - - if (Gst.MessageType.EOS in message.type) { - string next_uri; - - this.next_uri_lock.lock (); - next_uri = this.next_uri; - this.next_uri_lock.unlock (); - - if (next_uri == null) { - // no next track was arranged, we're done - this.stream_over (); - } - } - - return true; + bus.message["error"].connect ((message) => { + Error err; + string? debug; + message.parse_error (out err, out debug); + error ("gst playbin bus error: %s", err.message); }); - this.playbin.about_to_finish.connect (this.on_about_to_finish); + bus.message["warning"].connect ((message) => { + Error err; + string? debug; + message.parse_error (out err, out debug); + warning ("gst playbin bus warning: %s", err.message); + }); + + bus.message["async-done"].connect ((message) => { + assert (this.async_done_callback != null); + var cb = (owned) this.async_done_callback; + assert (this.async_done_callback == null); // sanity check + cb (); + }); + + bus.message["stream-start"].connect ((message) => { + int64 new_duration; + assert (this.playbin.query_duration (Gst.Format.TIME, out new_duration)); + this.duration = new_duration; + + string? next_uri = null; + + this.next_uri_lock.lock (); + next_uri = this.next_uri; + + if (next_uri != (string) this.playbin.current_uri) { + this.next_uri_lock.unlock (); + // WHOOPS! didn't actually switch to the track the play queue wanted + // we can still fix this though + assert (next_uri != null); + this.playbin.set_state (Gst.State.READY); + this.playbin.uri = next_uri; + this.playbin.set_state (Gst.State.PLAYING); + // no one will ever know + } else { + this.next_uri = null; + this.next_uri_lock.unlock (); + + this.stream_started (); + } + }); + + bus.message["eos"].connect ((message) => { + string next_uri; + + this.next_uri_lock.lock (); + next_uri = this.next_uri; + this.next_uri_lock.unlock (); + + if (next_uri == null) { + // no next track was arranged, we're done + this.stream_over (); + } + }); } private async void set_state (Gst.State state) { @@ -190,7 +196,7 @@ class Playbin : Object { // called when uri can be switched for gapless playback // need async queue because this might be called from a gstreamer thread - private void on_about_to_finish (dynamic Gst.Element playbin) { + private void about_to_finish (dynamic Gst.Element playbin) { this.next_uri_lock.lock (); string? next_uri = this.next_uri; this.next_uri_lock.unlock (); diff --git a/src/ui/window.vala b/src/ui/window.vala index 34e380c..7243fd0 100644 --- a/src/ui/window.vala +++ b/src/ui/window.vala @@ -131,10 +131,10 @@ class Ui.Window : Adw.ApplicationWindow { }); this.song = null; - this.playbin.set_position.connect ((sender, new_position) => { + this.playbin.notify["position"].connect (() => { // only set if we aren't seeking if (this.seek_timeout_id == 0) { - this.position = new_position; + this.position = this.playbin.position; } }); }