From: Nick Bowler Date: Fri, 28 Jun 2019 00:01:41 +0000 (-0400) Subject: mpdmenu: Factor out thumbnail generation. X-Git-Url: https://git.draconx.ca/gitweb/mpdhacks.git/commitdiff_plain/a93fdf47f9567f0542ef75207e3b5b26362b5620 mpdmenu: Factor out thumbnail generation. Prep work for making use of MPD albumart, move all calls to the thumbnailer into a single function, and adapt the menus to call the function once to generate an entire list of cover art. Drop the use of the --image option in the thumbnailer by poking at the cover art directly, since this will no longer work with MPD albumart. --- diff --git a/mpdmenu.pl b/mpdmenu.pl index be2c08f..9a7c77e 100755 --- a/mpdmenu.pl +++ b/mpdmenu.pl @@ -13,6 +13,7 @@ use strict; use Getopt::Long; use IO::Socket::INET6; +use Scalar::Util qw(reftype); use FindBin; use constant { @@ -27,6 +28,72 @@ binmode(STDOUT, ":utf8"); use Encode; my $SELF = "$FindBin::Bin/$FindBin::Script"; +my $MUSIC = $ENV{MUSIC} // "/srv/music"; + +# get_item_thumbnails({ options }, file, ...) +# get_item_thumbnails(file, ...) +# +# For each music file listed, obtain a thumbnail (if any) for the +# cover art. +# +# The first argument is a hash reference to control the mode of +# operation; it may be omitted for default options. +# +# get_item_thumbnails({ small => 1 }, ...) - smaller thumbnails +# +# The returned list consists of strings (in the same order as the filename +# arguments) suitable for use directly in FVWM menus; by default the filename +# is bracketed by asterisks (e.g., "*thumbnail.png*"); in small mode it is +# surrounded by % (e.g., "%thumbnail.png%"). If no cover art was found, the +# empty string is returned for that file. +sub get_item_thumbnails { + my @results = (); + my $flags = {}; + my @opts = (); + + $flags = shift if (reftype($_[0]) eq "HASH"); + return @results unless @_; + + my $c = "*"; + if ($flags->{small}) { + push @opts, "--small"; + $c = "%"; + } + + foreach (@_) { + open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh", "--music", + @opts, $_; + my $thumb = ; + chomp $thumb; + + $thumb = "$c$thumb$c" if (-f $thumb); + push @results, $thumb; + close THUMB; + die("thumbnail.zsh failed") if ($?); + } + + return @results; +} + +# Given a music filename, search for the cover art in the same directory. +sub mpd_cover_filename { + my ($dir) = @_; + my $file; + + $dir =~ s/\/[^\/]*$//; + foreach ("cover.png", "cover.jpg", "cover.tiff", "cover.bmp") { + if (-f "$dir/$_") { + $file = "$dir/$_"; + last; + } + } + return unless defined $file; + + # Follow one level of symbolic link to get to the scans directory. + $file = readlink($file) // $file; + $file = "$dir/$file" unless ($file =~ /^\//); + return $file; +} sub cmd { @@ -149,18 +216,14 @@ if (defined $album) { { # work around 'use locale' breaking s///i my $i = 0; use locale; - foreach (sort keys(%albums)) { - my $key = $_; - my $a_album = sanitise($key, 1); - open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh", - "--small", "--music", $albums{$key}; - my $thumb = ; - close THUMB; - die("Incompetent use of thumbnail.zsh") if ($?); + my @keys = sort keys %albums; + my @thumbs = get_item_thumbnails({ small => 1 }, + map { $albums{$_} } @keys); - $thumb =~ s/\n//sg; - $thumb = "%$thumb%" if (-f $thumb); + foreach my $key (@keys) { + my $a_album = sanitise($key, 1); + my $thumb = shift @thumbs; cmd("AddToMenu $menu \"$thumb$a_album\" Popup MenuMPDArt_$i"); @@ -240,12 +303,20 @@ if (defined $album) { { # work around 'use locale' breaking s///i use locale; + + my @thumbs = get_item_thumbnails({ small => 1 }, + map { $_->{file} } @titles); + for (my $i = 0; $i < @titles; $i++) { + $titles[$i]->{thumb} = $thumbs[$i]; + } + foreach (sort titlesort @titles) { - my ($t_file, $t_artist, $t_title, $t_id) = ( + my ($t_file, $t_artist, $t_title, $t_id, $thumb) = ( $_->{file}, $_->{Artist}, $_->{Title}, $_->{Id}, + $_->{thumb} ); # MPD searches are case-insensitive. @@ -254,15 +325,6 @@ if (defined $album) { $t_artist = sanitise($t_artist, 1); $t_title = sanitise($t_title, 1); - open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh", - "--small", "--music", $t_file; - my $thumb = ; - close(THUMB); - die("Incompetent use of thumbnail.zsh") if ($?); - - $thumb =~ s/\n//sg; - $thumb = "%$thumb%" if (-f $thumb); - cmd("AddToMenu $menu \"$thumb$t_artist - $t_title\"" ." Exec exec $FindBin::Bin/mpdexec.pl" ." playid $t_id"); @@ -303,20 +365,14 @@ if (defined $album) { } die("Failed data query\n") unless (keys(%entry) > 0); - open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh", - "--image", "--music", $entry{file}; - my $thumb = ; - my $scan = ; - close(THUMB); - die("Incompetent use of thumbnail.zsh") if ($?); - - $thumb =~ s/\n//sg; - $scan =~ s/\n//sg; + my ($thumb) = get_item_thumbnails($entry{file}); + if ($thumb) { + my $cover = mpd_cover_filename("$MUSIC/$entry{file}"); - if (-f $thumb) { - cmd("AddToMenu $menu \"*$thumb*\" " - ."Exec exec geeqie ".shellify($scan, 0)); + cmd("AddToMenu $menu \"$thumb\" " + ."Exec exec geeqie ".shellify($cover, 0)); } + cmd("AddToMenu $menu \"Title: ".sanitise($entry{Title}, 0) ."\" Popup MenuMPDTitle"); cmd("AddToMenu $menu \"Artist: ".sanitise($entry{Artist}, 0)