Skip to content

Commit d803fc2

Browse files
committed
Fix merge
1 parent fcb4cdd commit d803fc2

3 files changed

Lines changed: 141 additions & 20 deletions

File tree

src/AudioObject.vala

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,21 @@
55

66
public class Music.AudioObject : Object {
77
public string uri { get; construct; }
8-
public Gdk.Texture? texture { get; set; default = null; }
9-
public string album { get; set; }
10-
public string artist { get; set; }
11-
public string title { get; set; }
12-
public int64 duration { get; set; default = 0; }
13-
public string art_url { get; set; default = ""; }
8+
public Gdk.Texture? texture { get; private set; default = null; }
9+
public string album { get; private set; }
10+
public string artist { get; private set; }
11+
public string title { get; private set; }
12+
public int64 duration { get; private set; default = 0; }
13+
public string art_url { get; private set; default = ""; }
1414

1515
private static MetadataDiscoverer discoverer = new MetadataDiscoverer ();
1616

1717
public AudioObject (string uri) {
18-
Object (
19-
uri: uri,
20-
title: uri
21-
);
18+
Object (uri: uri);
2219
}
2320

2421
construct {
22+
title = uri;
2523
discoverer.request (this);
2624
}
2725

@@ -44,12 +42,29 @@ public class Music.AudioObject : Object {
4442
artist = _("Unknown");
4543
}
4644

47-
var sample = get_cover_sample (tag_list);
48-
if (sample != null) {
49-
var buffer = sample.get_buffer ();
45+
string art_hash = uri;
46+
if (_artist != null && _album != null) {
47+
art_hash = "%s:%s".printf (_artist, _album);
48+
}
5049

51-
if (buffer != null) {
52-
texture = Gdk.Texture.for_pixbuf (get_pixbuf_from_buffer (buffer));
50+
var art_file = File.new_for_path (Path.build_path (
51+
Path.DIR_SEPARATOR_S,
52+
get_art_cache_dir (),
53+
Checksum.compute_for_string (SHA256, art_hash)
54+
));
55+
56+
if (art_file.query_exists ()) {
57+
art_url = art_file.get_uri ();
58+
texture = Gdk.Texture.from_file (art_file);
59+
} else {
60+
var sample = get_cover_sample (tag_list);
61+
if (sample != null) {
62+
var buffer = sample.get_buffer ();
63+
64+
if (buffer != null) {
65+
texture = Gdk.Texture.for_pixbuf (get_pixbuf_from_buffer (buffer));
66+
save_art_file.begin (texture, art_file);
67+
}
5368
}
5469
}
5570
}
@@ -97,6 +112,28 @@ public class Music.AudioObject : Object {
97112
return pix;
98113
}
99114

115+
private async void save_art_file (Gdk.Texture? texture, File file) requires (texture != null) {
116+
try {
117+
DirUtils.create_with_parents (get_art_cache_dir (), 0755);
118+
119+
var ostream = yield file.create_async (NONE);
120+
yield ostream.write_bytes_async (texture.save_to_png_bytes ());
121+
122+
art_url = file.get_uri ();
123+
} catch (Error e) {
124+
critical ("Error saving artwork file: %s", e.message);
125+
}
126+
}
127+
128+
private string get_art_cache_dir () {
129+
return Path.build_path (
130+
Path.DIR_SEPARATOR_S,
131+
Environment.get_user_cache_dir (),
132+
GLib.Application.get_default ().application_id,
133+
"art"
134+
);
135+
}
136+
100137
public static bool equal_func (AudioObject a, AudioObject b) {
101138
return (a.uri == b.uri);
102139
}

src/MetadataDiscoverer.vala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-3.0-or-later
3+
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
4+
*/
5+
16
[SingleInstance]
27
public class Music.MetadataDiscoverer : Object {
3-
private Gst.PbUtils.Discoverer discoverer;
8+
private Gst.PbUtils.Discoverer? discoverer;
49
private HashTable<string, AudioObject> objects_to_update;
510

611
construct {
@@ -11,19 +16,21 @@ public class Music.MetadataDiscoverer : Object {
1116
} catch (Error e) {
1217
critical ("Unable to start Gstreamer Discoverer: %s", e.message);
1318
}
19+
1420
objects_to_update = new HashTable<string, AudioObject> (str_hash, str_equal);
1521
}
1622

17-
public void request (AudioObject audio) {
18-
objects_to_update.insert (audio.uri, audio);
23+
public void request (AudioObject audio) requires (discoverer != null && !objects_to_update.contains (audio.uri)) {
24+
objects_to_update[audio.uri] = audio;
1925
discoverer.start ();
2026
discoverer.discover_uri_async (audio.uri);
2127
}
2228

2329
private void relay_metadata (Gst.PbUtils.DiscovererInfo info, Error? err) {
2430
string uri = info.get_uri ();
25-
var audio_obj = objects_to_update.get (uri);
26-
objects_to_update.remove (uri);
31+
32+
var audio_obj = objects_to_update.take (uri, null);
33+
2734
switch (info.get_result ()) {
2835
case Gst.PbUtils.DiscovererResult.URI_INVALID:
2936
critical ("Couldn't read metadata for '%s': invalid URI.", uri);

src/PlaybackManager.vala

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,81 @@ public class Music.PlaybackManager : Object {
305305
next_action.set_enabled (next_sensitive);
306306
previous_action.set_enabled (previous_sensitive);
307307
}
308+
309+
private void on_items_changed () {
310+
has_items = queue_liststore.get_n_items () > 0;
311+
shuffle_action.set_enabled (queue_liststore.get_n_items () > 1);
312+
update_next_previous_sensitivity ();
313+
save_queue ();
314+
}
315+
316+
private void on_audio_changed () {
317+
playbin.set_state (Gst.State.NULL);
318+
if (current_audio != null) {
319+
playbin.uri = current_audio.uri;
320+
playbin.set_state (Gst.State.PLAYING);
321+
} else {
322+
playbin.uri = "";
323+
playback_position = 0;
324+
325+
if (progress_timer != 0) {
326+
Source.remove (progress_timer);
327+
progress_timer = 0;
328+
}
329+
}
330+
331+
update_next_previous_sensitivity ();
332+
333+
play_pause_action.set_enabled (current_audio != null);
334+
335+
var uri_last_played = current_audio != null ? current_audio.uri : "";
336+
settings.set_string ("uri-last-played", uri_last_played);
337+
}
338+
339+
private void save_queue () {
340+
string[] list_uri = new string[queue_liststore.n_items];
341+
342+
for (var i = 0; i < queue_liststore.n_items; i++) {
343+
var item = (Music.AudioObject)queue_liststore.get_item (i);
344+
list_uri[i] = item.uri;
345+
}
346+
347+
settings.set_strv ("previous-queue", list_uri);
348+
}
349+
350+
public void restore_queue () {
351+
// Restoring the queue overwrites the last played. So we need to retrieve it before taking care of the queue
352+
var uri_last_played = settings.get_string ("uri-last-played");
353+
var file_last_played = File.new_for_uri (uri_last_played);
354+
355+
var last_session_uri = settings.get_strv ("previous-queue");
356+
if (last_session_uri.length == 0) {
357+
return;
358+
}
359+
360+
var last_session_files = new File[last_session_uri.length];
361+
362+
for (var i = 0; i < last_session_uri.length; i++) {
363+
var uri = last_session_uri[i];
364+
var file = File.new_for_uri (uri);
365+
last_session_files[i] = file;
366+
}
367+
368+
var files_to_play = Application.loop_through_files (last_session_files);
369+
queue_files (files_to_play);
370+
371+
if (uri_last_played != "" && file_last_played.query_exists ()) {
372+
var audio_object = new AudioObject (uri_last_played);
373+
uint position = -1;
374+
if (!queue_liststore.find_with_equal_func (
375+
audio_object,
376+
(EqualFunc<AudioObject>) AudioObject.equal_func,
377+
out position
378+
)) {
379+
return;
380+
}
381+
382+
current_audio = (AudioObject) queue_liststore.get_item (position);
383+
}
384+
}
308385
}

0 commit comments

Comments
 (0)