]> diplodocus.org Git - flac-archive/blob - flac2mp3
Account for two Qobuz oddities in flac2mp3.
[flac-archive] / flac2mp3
1 #!/usr/local/bin/perl
2
3 =head1 NAME
4
5 B<flac2mp3> - transcode FLAC file to MP3 files
6
7 =head1 SYNOPSIS
8
9 B<flac2mp3> [B<--lame-options> I<lame-options>] [B<-q>] [B<-v>] I<file> [...]
10
11 =head1 DESCRIPTION
12
13 B<flac2mp3> transcodes the FLAC files I<file> to MP3 files. I<file>
14 may be the kind of FLAC file B<fa-flacd> generates. That is, it
15 contains a cue sheet, one TITLE tag per track listed therein, and
16 ARTIST, ALBUM, and DATE tags.
17
18 Note that lame is retarded, and parses B<LANG> directly itself! So, in order
19 for it to transcode textual tags, you must specify the encoding in LANG, e.g.
20 LANG=en_US.utf-8
21
22 =head1 OPTIONS
23
24 =over 4
25
26 =item B<--lame-options> I<lame-options>
27
28 Pass I<lame-options> to B<lame>. This ends up being passed to the
29 shell, so feel free to take advantage of that. You'll almost
30 certainly have to put I<lame-options> in single quotes.
31
32 =item B<-q> [B<--quiet>]
33
34 Suppress status information. This option is passed along to B<flac>
35 and B<lame>.
36
37 =item B<-v> [B<--verbose>]
38
39 Print diagnostic information. This option is passed along to B<flac>
40 and B<lame>.
41
42 =back
43
44 =head1 AUTHORS
45
46 Written by Eric Gillespie <epg@pretzelnet.org>.
47
48 =cut
49
50 package epg::flac::archive::mp3;
51
52 use v5.12;
53 use warnings;
54
55 use File::Temp;
56 use FindBin;
57
58 require "$FindBin::Bin/tags.pl";
59 epg::flac::archive::tags->import(
60 qw[
61 disc_tags
62 read_tags
63 mangle_for_file_name
64 quote
65 two_digits
66 ]);
67
68 sub flac2mp3 {
69 my $quoted_flac = quote(shift);
70 my $tags = shift;
71 my ($artist, $album, $date, $discnumber) = disc_tags(%$tags);
72
73 # TODO resurrect whole-disc FLAC?
74 # Stupid hack: only a single-track file should have the
75 # TRACKNUMBER tag, so use it if set for the first pass through
76 # the loop. At the end of the loop, we'll set $track for the
77 # next run, so this continues to work for multi-track files.
78 # if track == None:
79 # track = 1
80 # else:
81 # track = int(track)
82
83 my $tracknumber = epg::flac::archive::tags::one(TRACKNUMBER => $tags);
84 my $title = epg::flac::archive::tags::one(TITLE => $tags);
85 # TODO restore PARTNUMBER and VERSION next time i need them
86
87 say('metaflac --export-picture-to=flac2mp3.cover.$$', " $quoted_flac && pic_options=", '"--ti flac2mp3.cover.$$"');
88
89 # This is an old TODO; what's wrong with --ty ?
90 # TODO: Look at TDOR, TDRL, TDRC for date.
91 say(join(' ',
92 'flac',
93 '-cd',
94 $quoted_flac,
95 '|',
96 'lame',
97 '--id3v2-only',
98 '--id3v2-latin1',
99 '--pad-id3v2-size', 0,
100 '--preset standard',
101 '--ta',
102 quote($artist),
103 '--tl',
104 quote($album),
105 '--tn',
106 quote($tracknumber),
107 '--tt',
108 quote($title),
109 '--ty',
110 quote($date),
111 '$pic_options',
112 #(map { ('--tv', quote("TPE2=$_")) } @{$albumartist}),
113 (map { ('--tv', quote("TPOS=$_")) } @{$discnumber}),
114 '-',
115 quote(
116 mangle_for_file_name(
117 join(' ',
118 $artist,
119 $album,
120 (map { two_digits($_) } @{$discnumber}),
121 two_digits($tracknumber),
122 $title,
123 ))
124 . '.mp3'
125 )
126 ));
127 say('unset pic_options');
128 }
129
130 sub read_tags_metaflac {
131 my $fn = shift;
132 open(my $fh, '-|', 'metaflac', '--no-utf8-convert', '--export-tags-to=-', $fn) || die("metalfac: $!");
133 my @result = read_tags($fh);
134 if (!close($fh)) {
135 if ($! == 0) {
136 die("metaflac exited $?")
137 }
138 die("close(metaflac): $!")
139 }
140 @result
141 }
142
143 sub main {
144 for my $fn (@_) {
145 my ($tags) = read_tags_metaflac($fn);
146 flac2mp3($fn, $tags);
147 }
148 say('rm -f flac2mp3.cover.$$');
149
150 return 0;
151 }
152
153 if (!caller) {
154 exit(main(@ARGV))
155 }
156
157 1;