#!/usr/local/bin/perl =head1 NAME B - transcode FLAC file to MP3 files =head1 SYNOPSIS B [B<--lame-options> I] [B<-q>] [B<-v>] I [...] =head1 DESCRIPTION B transcodes the FLAC files I to MP3 files. I may be the kind of FLAC file B generates. That is, it contains a cue sheet, one TITLE tag per track listed therein, and ARTIST, ALBUM, and DATE tags. Note that lame is retarded, and parses B directly itself! So, in order for it to transcode textual tags, you must specify the encoding in LANG, e.g. LANG=en_US.utf-8 =head1 OPTIONS =over 4 =item B<--lame-options> I Pass I to B. This ends up being passed to the shell, so feel free to take advantage of that. You'll almost certainly have to put I in single quotes. =item B<-q> [B<--quiet>] Suppress status information. This option is passed along to B and B. =item B<-v> [B<--verbose>] Print diagnostic information. This option is passed along to B and B. =back =head1 AUTHORS Written by Eric Gillespie . =cut package epg::flac::archive::mp3; use v5.12; use warnings; use File::Temp; use FindBin; require "$FindBin::Bin/tags.pl"; epg::flac::archive::tags->import( qw[ disc_tags read_tags mangle_for_file_name quote ]); sub flac2mp3 { my %a = @_; my $quoted_flac = quote($a{flac}); say('if metaflac --export-picture-to=flac2mp3.cover.$$ ', $quoted_flac, '; then'); say(' pic_options="--ti flac2mp3.cover.$$"'); say('fi'); # This is an old TODO; what's wrong with --ty ? # TODO: Look at TDOR, TDRL, TDRC for date. say(join(' ', 'flac', '-cd', $quoted_flac, '|', 'lame', '--id3v2-only', '--id3v2-latin1', '--pad-id3v2-size', 0, '--preset standard', '--ta', quote($a{artist}), '--tl', quote($a{album}), '--tn', quote($a{track}), '--tt', quote($a{title}), '--ty', quote($a{date}), '$pic_options', (map { ('--tv', quote("TPE2=$_")) } @{$a{albumartist}}), (map { ('--tv', quote("TPOS=$_")) } @{$a{discnumber}}), '-', quote( mangle_for_file_name( join(' ', $a{artist}, $a{album}, (map { sprintf('%02d', $_) } @{$a{discnumber}}), $a{track}, $a{title}, )) . '.mp3' ) )); say('unset pic_options'); say('rm -f flac2mp3.cover.$$'); } sub read_tags_metaflac { my $fn = shift; open(my $fh, '-|', 'metaflac', '--no-utf8-convert', '--export-tags-to=-', $fn) || die("metalfac: $!"); my @result = read_tags($fh); if (!close($fh)) { if ($! == 0) { die("metaflac exited $?") } die("close(metaflac): $!") } @result } sub main { for my $fn (@_) { my ($tags) = read_tags_metaflac($fn); my ($album, $artist, $date, $discnumber) = disc_tags($tags); # TODO resurrect whole-disc FLAC? # Stupid hack: only a single-track file should have the # TRACKNUMBER tag, so use it if set for the first pass through # the loop. At the end of the loop, we'll set $track for the # next run, so this continues to work for multi-track files. # if track == None: # track = 1 # else: # track = int(track) { my $tracknumber = epg::flac::archive::tags::one(TRACKNUMBER => $tags); my $title = epg::flac::archive::tags::one(TITLE => $tags); # TODO restore PARTNUMBER and VERSION net time i need them flac2mp3( artist => $artist, album => $album, date => $date, discnumber => $discnumber, track => $tracknumber, title => $title, flac => $fn, ) } } return 0; } if (!caller) { exit(main(@ARGV)) } 1;