]> diplodocus.org Git - flac-archive/blob - flac2mp3
Collapse fa-rip and fa-tags into a single Perl program, fa-rip.
[flac-archive] / flac2mp3
1 #! /usr/bin/env perl
2
3 # $Id$
4
5 =head1 NAME
6
7 B<flac2mp3> - transcode FLAC file to MP3 files
8
9 =head1 SYNOPSIS
10
11 B<flac2mp3> I<file>
12
13 =head1 DESCRIPTION
14
15 B<flac2mp3> transcodes the FLAC file I<file> to MP3 files. I<file> is
16 the kind of FLAC file B<fa-flacd> generates. That is, it contains a
17 cue sheet, one TITLE tag per track listed therein, and ARTIST, ALBUM,
18 and DATE tags.
19
20 =cut
21
22 use strict;
23 use warnings;
24
25 use Pod::Usage;
26
27 sub tformat {
28 return sprintf('%02d:%02d.%02d', @_);
29 }
30
31 sub get_decode_args {
32 my $fn = shift;
33 my @l;
34
35 open(F, '-|', 'metaflac', '--export-cuesheet-to=-', $fn);
36 while (<F>) {
37 /INDEX 01 (\d\d):(\d\d):(\d\d)$/ or next;
38 push(@l, [$1, $2, $3]);
39 }
40
41 my @args;
42 for my $i (0..$#l) {
43 my $arg = ["--skip=" . tformat(@{$l[$i]})];
44 my $next = $l[$i+1];
45 if (defined($next)) {
46 if ($next->[2] == 0) {
47 if ($next->[1] == 0) {
48 push(@$arg, '--until=' . tformat($next->[0] - 1, 59, 74));
49 } else {
50 push(@$arg, '--until=' . tformat($next->[0], $next->[1] - 1,
51 74));
52 }
53 } else {
54 push(@$arg, '--until=' . tformat($next->[0], $next->[1],
55 $next->[2] - 1));
56 }
57 }
58 push(@args, $arg);
59 }
60
61 return @args;
62 }
63
64 # Return the ARTIST, ALBUM, and DATE tags followed by the TITLE tags
65 # in the file FN.
66 sub get_tags {
67 my $fn = shift;
68 my $tag;
69 my $value;
70 my $artist;
71 my $album;
72 my $date;
73 my @titles;
74
75 open(TAGS, '-|', 'metaflac', '--export-vc-to=-', $fn)
76 or die("open(metaflac --export-vc-to=- $fn): $!");
77 while (<TAGS>) {
78 chomp;
79
80 ($tag, $value) = split(/=/, $_, 2);
81
82 if (/^ARTIST=/) {
83 $artist = $value;
84 } elsif (/^ALBUM=/) {
85 $album = $value;
86 } elsif (/^DATE=/) {
87 $date = $value;
88 } elsif (/TITLE=/) {
89 push(@titles, $value);
90 }
91 }
92 close(TAGS) or die("close(metaflac --export-vc-to=- $fn): $?");
93
94 return ($artist, $album, $date, @titles);
95 }
96
97 sub flac2mp3 {
98 my $fn = shift;
99 my $title = shift;
100 my $artist = shift;
101 my $album = shift;
102 my $date = shift;
103 my $track = shift;
104 my $skip_arg = shift;
105 my $until_arg = shift;
106 my $outfile;
107
108 # We'll be putting these in single quotes, so we need to escape
109 # any single quotes in the filename by closing the quote ('),
110 # putting an escaped quote (\'), and then reopening the quote (').
111 for ($fn, $title, $artist, $album, $date) {
112 s/'/'\\''/;
113 }
114
115 $outfile = sprintf("$artist ($album) \%02s $title.mp3", $track);
116 $outfile =~ s/\//_/g;
117
118 $until_arg ||= '';
119 # XXX
120 system("flac -cd $skip_arg $until_arg '$fn' | lame --preset standard --tt '$title' --ta '$artist' --tl '$album' --ty '$date' --tn $track - '$outfile'");
121 }
122
123 MAIN: {
124 my $fn = shift or pod2usage();
125 my @args = get_decode_args($fn);
126 my ($artist, $album, $date, @titles) = get_tags($fn);
127
128 for my $i (0..$#titles) {
129 flac2mp3($fn, $titles[$i], $artist, $album, $date, $i + 1,
130 @{$args[$i]});
131 }
132 }
133
134 \f
135 __END__
136
137 =head1 AUTHORS
138
139 Written by Eric Gillespie <epg@pretzelnet.org>.
140
141 =cut
142
143 # Local variables:
144 # cperl-indent-level: 4
145 # perl-indent-level: 4
146 # indent-tabs-mode: nil
147 # End:
148
149 # vi: set tabstop=4 expandtab: