Add MP4 support
[app-musicexpo.git] / lib / App / MusicExpo.pm
index 9927bfc0b9dbff7507e84c93659fe1e69022a94e..ebee6efc784f18ae802565dcc0c3a02a79fd8e81 100644 (file)
@@ -3,19 +3,20 @@ use v5.14;
 use strict;
 use warnings;
 
-our $VERSION = 0.003001;
+our $VERSION = '0.003003';
 
 use Audio::FLAC::Header qw//;
 use HTML::Template::Compiled qw//;
 use Memoize qw/memoize/;
 use MP3::Tag qw//;
 use Ogg::Vorbis::Header::PurePerl;
+use MP4::Info qw/get_mp4tag get_mp4info/;
 
 use DB_File qw//;
 use File::Basename qw/fileparse/;
 use Fcntl qw/O_RDWR O_CREAT/;
 use Getopt::Long;
-use JSON;
+use JSON::MaybeXS;
 use Storable qw/thaw freeze/;
 
 ##################################################
@@ -93,24 +94,51 @@ sub vorbisinfo{
        }
 }
 
+sub mp4_format ($){
+       my $encoding = $_[0];
+       return 'AAC' if $encoding eq 'mp4a';
+       return 'ALAC' if $encoding eq 'alac';
+       "MP4-$encoding"
+}
+
+sub mp4info{
+       my $file=$_[0];
+       my %tag = %{get_mp4tag $file};
+       my %info = %{get_mp4info $file};
+       $file = scalar fileparse $file;
+
+       freeze +{
+               format => mp4_format $info{ENCODING},
+               title => $tag{TITLE} || '?',
+               artist => $tag{ARTIST} || '?',
+               year => $tag{YEAR} || '?',
+               album => $tag{ALBUM} || '?',
+               tracknumber => $tag{TRACKNUM} || '?',
+               tracktotal => ($tag{TRKN} ? $tag{TRKN}->[1] : undef) || '?',
+               genre => $tag{GENRE} || '?',
+               file => $file,
+       };
+}
+
 sub normalizer{
        "$_[0]|".(stat $_[0])[9]
 }
 
 sub run {
-       tie my %cache, 'DB_File', $cache, O_RDWR|O_CREAT, 0644 unless $cache eq '';
-       memoize 'flacinfo', NORMALIZER => \&normalizer, LIST_CACHE => 'MERGE', SCALAR_CACHE => [HASH => \%cache] unless $cache eq '';
-       memoize 'mp3info' , NORMALIZER => \&normalizer, LIST_CACHE => 'MERGE', SCALAR_CACHE => [HASH => \%cache] unless $cache eq '';
-       memoize 'vorbisinfo' , NORMALIZER => \&normalizer, LIST_CACHE => 'MERGE', SCALAR_CACHE => [HASH => \%cache] unless $cache eq '';
+       if ($cache) {
+               tie my %cache, 'DB_File', $cache, O_RDWR|O_CREAT, 0644;
+               memoize $_, NORMALIZER => \&normalizer, LIST_CACHE => 'MERGE', SCALAR_CACHE => [HASH => \%cache] for qw/flacinfo mp3info vorbisinfo mp4info/;
+       }
 
        my %files;
        for my $file (@ARGV) {
                my $info;
-               $info = thaw flacinfo $file if $file =~ /.flac$/i;
-               $info = thaw mp3info $file if $file =~ /.mp3$/i;
-               $info = thaw vorbisinfo $file if $file =~ /.og(?:g|a)$/i;
+               $info = thaw flacinfo $file if $file =~ /\.flac$/i;
+               $info = thaw mp3info $file if $file =~ /\.mp3$/i;
+               $info = thaw vorbisinfo $file if $file =~ /\.og(?:g|a)$/i;
+               $info = thaw mp4info $file if $file =~ /\.mp4|\.aac|\.m4a$/i;
                next unless defined $info;
-               my $basename = fileparse $file, '.flac', '.mp3', '.ogg', '.oga';
+               my $basename = fileparse $file, '.flac', '.mp3', '.ogg', '.oga', '.mp4', '.aac', '.m4a';
                $files{$basename} //= [];
                push $files{$basename}, $info;
        }
@@ -129,7 +157,7 @@ sub run {
                push @files, \%entry
        }
 
-       my $json = JSON->new->utf8->canonical->encode({files => \@files, prefix => $prefix});
+       my $json = JSON::MaybeXS->new(canonical => 1)->encode({files => \@files, prefix => $prefix});
        $json =~ s/</&lt;/g;
        $json =~ s/>/&gt;/g;
        $ht->param(files=>[sort { $a->{title} cmp $b->{title} } @files], prefix => $prefix, json => $json);
This page took 0.011709 seconds and 4 git commands to generate.