11/*
22 * SPDX-License-Identifier: LGPL-3.0-or-later
3- * SPDX-FileCopyrightText: 2021-2022 elementary, Inc. (https://elementary.io)
3+ * SPDX-FileCopyrightText: 2021-2026 elementary, Inc. (https://elementary.io)
44 */
55
66public class Music.PlaybackManager : Object {
@@ -14,13 +14,15 @@ public class Music.PlaybackManager : Object {
1414 }
1515 public int64 playback_position { get ; private set ; }
1616 public signal void invalids_found (int count );
17+ public signal void duplicates_found (int count );
1718
1819 private static GLib . Once<PlaybackManager > instance;
1920 public static unowned PlaybackManager get_default () {
2021 return instance. once (() = > { return new PlaybackManager (); });
2122 }
2223
2324 private dynamic Gst . Element playbin;
25+ private dynamic Gst . Element rgvolume;
2426 private uint progress_timer = 0 ;
2527 private Settings settings;
2628
@@ -47,6 +49,8 @@ public class Music.PlaybackManager : Object {
4749 queue_liststore = new ListStore (typeof (AudioObject ));
4850
4951 playbin = Gst . ElementFactory . make (" playbin" , " playbin" );
52+ rgvolume = Gst . ElementFactory . make (" rgvolume" , " replaygain" );
53+ playbin. set_property (" audio-filter" , rgvolume);
5054
5155 var bus = playbin. get_bus ();
5256 bus. add_watch (0 , bus_callback);
@@ -101,10 +105,26 @@ public class Music.PlaybackManager : Object {
101105 // Files[] must not contain any null entries
102106 public void queue_files (File [] files ) {
103107 int invalids = 0 ;
108+ int duplicates = 0 ;
109+ int added_tracks = 0 ;
104110 foreach (unowned var file in files) {
105111 if (file. query_exists () && " audio" in ContentType . guess (file. get_uri (), null , null )) {
106- var audio_object = new AudioObject (file. get_uri ());
107- queue_liststore. append (audio_object);
112+ uint pos = 0 ;
113+ bool found = false ;
114+ Object ? item = queue_liststore. get_item (pos++ );
115+ while (item != null && ! found) {
116+ if (((AudioObject )item). uri == file. get_uri ()) {
117+ found = true ;
118+ }
119+
120+ item = queue_liststore. get_item (pos++ );
121+ }
122+ if (! found) {
123+ queue_liststore. append (new AudioObject (file. get_uri ()));
124+ added_tracks++ ;
125+ } else {
126+ duplicates++ ;
127+ }
108128 } else {
109129 invalids++ ;
110130 continue ;
@@ -114,6 +134,9 @@ public class Music.PlaybackManager : Object {
114134 if (invalids > 0 ) {
115135 invalids_found (invalids);
116136 }
137+ if (duplicates > 0 ) {
138+ duplicates_found (duplicates);
139+ }
117140
118141 if (current_audio == null ) {
119142 var audio_object = (AudioObject ) queue_liststore. get_object (0 );
@@ -123,7 +146,6 @@ public class Music.PlaybackManager : Object {
123146 } else {
124147 // Don't notify on app startup or if the app is focused
125148 var application = (Gtk . Application ) GLib . Application . get_default ();
126- var added_tracks = files. length - invalids;
127149 if (
128150 ! application. get_active_window (). is_active &&
129151 added_tracks > 0
0 commit comments