playbin refactor
This commit is contained in:
parent
4256778e95
commit
629bc782fc
2 changed files with 72 additions and 66 deletions
134
src/playbin.vala
134
src/playbin.vala
|
@ -16,17 +16,17 @@ class Playbin : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool mute {
|
public bool mute {
|
||||||
get { return playbin.mute; }
|
get { return this.playbin.mute; }
|
||||||
set { playbin.mute = value; }
|
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 int64 duration { get; private set; }
|
||||||
|
|
||||||
public signal void stream_started ();
|
public signal void stream_started ();
|
||||||
public signal void stream_over ();
|
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";
|
source.user_agent = "audrey/linux";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,79 +34,85 @@ class Playbin : Object {
|
||||||
this.playbin = Gst.ElementFactory.make ("playbin3", null);
|
this.playbin = Gst.ElementFactory.make ("playbin3", null);
|
||||||
assert (this.playbin != 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
|
// regularly update position
|
||||||
Timeout.add (500, () => {
|
Timeout.add (500, () => {
|
||||||
int64 new_position;
|
int64 new_position;
|
||||||
if (this.playbin.query_position (Gst.Format.TIME, out 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
|
// keep rerunning
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.playbin.get_bus ().add_watch (Priority.DEFAULT, (bus, message) => {
|
var bus = this.playbin.get_bus ();
|
||||||
// message.type actually seems to be flags
|
bus.add_signal_watch ();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Gst.MessageType.ASYNC_DONE in message.type) {
|
bus.message["error"].connect ((message) => {
|
||||||
assert (this.async_done_callback != null);
|
Error err;
|
||||||
var cb = (owned) this.async_done_callback;
|
string? debug;
|
||||||
assert (this.async_done_callback == null); // sanity check
|
message.parse_error (out err, out debug);
|
||||||
cb ();
|
error ("gst playbin bus error: %s", err.message);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
private async void set_state (Gst.State state) {
|
||||||
|
@ -190,7 +196,7 @@ class Playbin : Object {
|
||||||
|
|
||||||
// called when uri can be switched for gapless playback
|
// called when uri can be switched for gapless playback
|
||||||
// need async queue because this might be called from a gstreamer thread
|
// 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 ();
|
this.next_uri_lock.lock ();
|
||||||
string? next_uri = this.next_uri;
|
string? next_uri = this.next_uri;
|
||||||
this.next_uri_lock.unlock ();
|
this.next_uri_lock.unlock ();
|
||||||
|
|
|
@ -131,10 +131,10 @@ class Ui.Window : Adw.ApplicationWindow {
|
||||||
});
|
});
|
||||||
this.song = null;
|
this.song = null;
|
||||||
|
|
||||||
this.playbin.set_position.connect ((sender, new_position) => {
|
this.playbin.notify["position"].connect (() => {
|
||||||
// only set if we aren't seeking
|
// only set if we aren't seeking
|
||||||
if (this.seek_timeout_id == 0) {
|
if (this.seek_timeout_id == 0) {
|
||||||
this.position = new_position;
|
this.position = this.playbin.position;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue