fix seeking hah

This commit is contained in:
Erica Z 2024-10-16 22:24:48 +02:00
parent e1b6b19c03
commit 2fe276bfbd
3 changed files with 28 additions and 31 deletions

View file

@ -166,6 +166,10 @@ class Playbin : GLib.Object {
assert (this.playbin.query_duration (Gst.Format.TIME, out duration)); assert (this.playbin.query_duration (Gst.Format.TIME, out duration));
this.duration = duration; this.duration = duration;
// cancel any queued seeks
this.queued_seek = -1;
this.update_position = true;
this.position = 0; this.position = 0;
bool continues = this.next_gapless; bool continues = this.next_gapless;
@ -202,7 +206,17 @@ class Playbin : GLib.Object {
Gst.State new_state; Gst.State new_state;
message.parse_state_changed (null, out new_state, null); message.parse_state_changed (null, out new_state, null);
this.update_position = new_state == Gst.State.PLAYING; if (new_state == Gst.State.PLAYING) {
if (queued_seek != -1) {
if (this.playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, this.queued_seek)) {
this.queued_seek = -1;
} else {
warning ("could not reapply queued seek after state changed changed to playing, retrying later");
}
} else {
this.update_position = true;
}
}
}); });
bus.message["eos"].connect ((message) => { bus.message["eos"].connect ((message) => {
@ -210,9 +224,14 @@ class Playbin : GLib.Object {
}); });
} }
private int64 queued_seek = -1;
public void seek (int64 position) { public void seek (int64 position) {
this.position = position;
this.update_position = false;
if (!this.playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, position)) { if (!this.playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE, position)) {
warning ("could not seek"); // try to queue this seek for later
queued_seek = position;
} }
} }

View file

@ -136,7 +136,7 @@ template $UiWindow: Adw.ApplicationWindow {
"numeric", "numeric",
] ]
label: bind $format_timestamp (template.position) as <string>; label: bind $format_timestamp (template.playbin as <$Playbin>.position) as <string>;
} }
[center] [center]
@ -148,7 +148,7 @@ template $UiWindow: Adw.ApplicationWindow {
adjustment: Adjustment { adjustment: Adjustment {
lower: 0; lower: 0;
value: bind template.position; value: bind template.playbin as <$Playbin>.position;
upper: bind template.playbin as <$Playbin>.duration; upper: bind template.playbin as <$Playbin>.duration;
}; };

View file

@ -11,8 +11,6 @@ class Ui.Window : Adw.ApplicationWindow {
private Subsonic.Client api; private Subsonic.Client api;
public int64 position { get; private set; }
public double volume { public double volume {
get { return this.playbin.volume; } get { return this.playbin.volume; }
set { this.playbin.volume = value; } set { this.playbin.volume = value; }
@ -114,13 +112,6 @@ class Ui.Window : Adw.ApplicationWindow {
}); });
} }
}); });
this.playbin.notify["position"].connect (() => {
// only set if we aren't seeking
if (this.seek_timeout_id == 0) {
this.position = this.playbin.position;
}
});
} }
[GtkCallback] private void on_sidebar_row_activated (Gtk.ListBoxRow row) { [GtkCallback] private void on_sidebar_row_activated (Gtk.ListBoxRow row) {
@ -138,21 +129,8 @@ class Ui.Window : Adw.ApplicationWindow {
return "%02d:%02d".printf (s/60, s%60); return "%02d:%02d".printf (s/60, s%60);
} }
private void seek_impl (int64 position) {
this.position = position;
if (this.seek_timeout_id == 0) {
this.seek_timeout_id = Timeout.add (500, () => {
playbin.seek(this.position);
this.seek_timeout_id = 0;
return false;
});
}
}
// same timeout logic as https://code.videolan.org/videolan/npapi-vlc/blob/6eae0ffb9cbaf8f6e04423de2ff38daabdf7cae3/npapi/vlcplugin_gtk.cpp#L312
private uint seek_timeout_id = 0;
[GtkCallback] private bool on_play_position_seek (Gtk.Range range, Gtk.ScrollType scroll_type, double value) { [GtkCallback] private bool on_play_position_seek (Gtk.Range range, Gtk.ScrollType scroll_type, double value) {
this.seek_impl((int64) value); this.playbin.seek ((int64) value);
return false; return false;
} }
@ -202,16 +180,16 @@ class Ui.Window : Adw.ApplicationWindow {
[GtkCallback] private void seek_backward () { [GtkCallback] private void seek_backward () {
// 10 seconds // 10 seconds
int64 new_position = position - 10 * Gst.SECOND; int64 new_position = playbin.position - 10 * Gst.SECOND;
if (new_position < 0) new_position = 0; if (new_position < 0) new_position = 0;
this.seek_impl (new_position); this.playbin.seek (new_position);
} }
[GtkCallback] private void seek_forward () { [GtkCallback] private void seek_forward () {
// 10 seconds // 10 seconds
int64 new_position = position + 10 * Gst.SECOND; int64 new_position = playbin.position + 10 * Gst.SECOND;
if (new_position > this.playbin.duration) new_position = this.playbin.duration; if (new_position > this.playbin.duration) new_position = this.playbin.duration;
this.seek_impl (new_position); this.playbin.seek (new_position);
} }
[GtkCallback] private string song_title (Subsonic.Song? song) { [GtkCallback] private string song_title (Subsonic.Song? song) {