diff --git a/data/music.gschema.xml b/data/music.gschema.xml
index e4ffeab87..bbb08d850 100644
--- a/data/music.gschema.xml
+++ b/data/music.gschema.xml
@@ -22,6 +22,11 @@
The last song played by Music
A string representing the uri of the last played music file
+
+ 0
+ Playback progression of the last song played by Music
+ Number of seconds elapsed since the beginning of the last track that was played
+
475
diff --git a/src/PlaybackManager.vala b/src/PlaybackManager.vala
index d9c20c76d..8dc303e9e 100644
--- a/src/PlaybackManager.vala
+++ b/src/PlaybackManager.vala
@@ -42,7 +42,6 @@ public class Music.PlaybackManager : Object {
private PlaybackManager () {}
construct {
- settings = new Settings ("io.elementary.music");
queue_liststore = new ListStore (typeof (AudioObject));
playbin = Gst.ElementFactory.make ("playbin", "playbin");
@@ -87,8 +86,12 @@ public class Music.PlaybackManager : Object {
bind_property ("has-items", clear_action, "enabled", SYNC_CREATE);
}
+ public void seek_to_progress_nano_seconds (int64 progress) {
+ playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH, progress);
+ }
+
public void seek_to_progress (double percent) {
- playbin.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH, (int64)(percent * current_audio.duration));
+ seek_to_progress_nano_seconds ((int64)(percent * current_audio.duration));
}
// Files[] must not contain any null entries
@@ -185,6 +188,13 @@ public class Music.PlaybackManager : Object {
playbin.query_position (Gst.Format.TIME, out position);
playback_position = position.clamp (0, current_audio.duration);
+ int playback_position_seconds = (int)(playback_position / 1000000000);
+ // Save progress every other second, to reduce disk writes
+ if (playback_position_seconds % 2 == 0) {
+ debug ("setting progress: " + (playback_position_seconds).to_string () + "s");
+ settings.set_int ("progression-last-played", playback_position_seconds);
+ }
+
return Source.CONTINUE;
});
} else {
@@ -380,6 +390,27 @@ public class Music.PlaybackManager : Object {
}
current_audio = (AudioObject) queue_liststore.get_item (position);
+
+ // Read then restore saved progress
+ var progression_last_played_seconds = settings.get_int ("progression-last-played");
+ if (progression_last_played_seconds > 0) {
+ int64 progression_last_played = (int64)progression_last_played_seconds * 1000000000;
+
+ // Wait for current_audio.duration to be set by the object responsible for setting it
+ GLib.Timeout.add (50, () => {
+ if (current_audio.duration != 0) {
+ // Do not seek if duration is inferior to seeking position
+ if (current_audio.duration > progression_last_played) {
+ info ("saved progress found and valid, restoring it: %i", progression_last_played_seconds);
+ seek_to_progress_nano_seconds (progression_last_played);
+ }
+ return Source.REMOVE;
+ }
+
+ // Track metadata are not set yet, continue to wait before restoring playback position
+ return Source.CONTINUE;
+ });
+ }
}
}
}