my $sock;
-# Returns a hash reference containing all tracks in the current play queue.
-# The hash keys are filenames.
+# Returns a hash reference mapping filenames to an array reference listing
+# the queue IDs for that file in the current play queue.
sub get_tracks_in_play_queue {
my %matches;
my $entry;
if (/^(\w+): (.*)$/) {
if ($1 eq "file") {
- if (exists($matches{$2})) {
- $entry = $matches{$2};
- } else {
- $entry = {};
- $matches{$2} = $entry;
- }
- }
-
- if (exists($entry->{$1})) {
- $entry->{$1}->{$2} = 1;
- } else {
- $entry->{$1} = { $2 => 1 }
+ $entry = $matches{$2} //= [];
+ } elsif ($1 eq "Id") {
+ push @$entry, $2;
}
}
}
$sock = MPD::connect();
# Retrieve the current play queue and target play queue.
+MPD::run("tagtypes", "clear");
my $current = get_tracks_in_play_queue();
my $target = get_playlist_files($ARGV[0]);
MPD::exec("command_list_begin");
for (my $i = 0; $i < @$target; $i++) {
my $f = $target->[$i];
- my $ids = $current->{$f}->{Id};
-
- my $id = (keys %$ids)[0];
- delete $ids->{$id};
-
- # Remove tracks with no unused queue IDs
- delete $current->{$f} unless (keys %$ids > 0);
+ my $id = shift @{ $current->{$f} };
if (defined $id) {
MPD::exec("moveid", $id, $i);
}
# Remove any tracks left from the old play queue.
-foreach (keys %$current) {
- my $ids = $current->{$_}->{Id};
- foreach (keys %$ids) {
- MPD::exec("deleteid", $_);
- }
-}
-
-MPD::exec("command_list_end");
-while (<$sock>) {
- last if /^OK$/;
- die($_) if /^ACK/;
-}
+MPD::exec("deleteid", $_) foreach (map { @$_ } values %$current);
+MPD::run("command_list_end");