]> diplodocus.org Git - flac-archive/blob - fa-encode
5f98151b5b17b21f581aea90bdcd0b442048520f
[flac-archive] / fa-encode
1 #!/usr/local/bin/perl
2
3 =head1 NAME
4
5 B<fa-encode> - encode WAV files to FLAC
6
7 =head1 SYNOPSIS
8
9 B<fa-encode> [B<-d> I<artist-directory>] B<input-directory>
10
11 I<artist-directory> defaults to the album B<ARTIST> in the tags file; one of
12 these is required.
13
14 TODO: implement B<-d>
15
16 =cut
17
18 package epg::flac::archive::encode;
19
20 use v5.12;
21 use warnings;
22
23 use FindBin;
24 use Pod::Usage;
25
26 require "$FindBin::Bin/tags.pl";
27 epg::flac::archive::tags->import(
28 qw[
29 read_tags
30 mangle_for_file_name
31 quote
32 two_digits
33 ]);
34
35 sub main {
36 my $input_directory = shift || pod2usage();
37 my $fn = "$input_directory/tags";
38 open(my $fh, '<', $fn) || die("open($fn): $!");
39 my ($album, $tracks) = read_tags($fh);
40 if (!defined($album->{ALBUM}) || scalar(@{$album->{ALBUM}}) != 1) {
41 die('exactly one ALBUM tag required')
42 }
43 my $album_tag = $album->{ALBUM}->[0];
44 # TODO -d support
45 if (!defined($album->{ARTIST}) || scalar(@{$album->{ARTIST}}) != 1) {
46 die('exactly one ARTIST tag required')
47 }
48 my $artist = $album->{ARTIST}->[0];
49
50 my $date;
51 if (defined($album->{DATE})) {
52 if (scalar(@{$album->{DATE}}) != 1) {
53 die('one or zero DATE tags required')
54 }
55 $date = $album->{DATE}->[0];
56 }
57 my @discnumber = ();
58 if (defined($album->{DISCNUMBER})) {
59 if (scalar(@{$album->{DISCNUMBER}}) != 1) {
60 die('one or zero DISCNUMBER tags required')
61 }
62 @discnumber = ($album->{DISCNUMBER}->[0]);
63 }
64
65 my $dir = join('/', '..', mangle_for_file_name($artist), mangle_for_file_name($album_tag));
66
67 say('set -ex');
68 say('cd ', quote($input_directory));
69 say('mkdir -p ', quote($dir));
70 my $tracknum = 0;
71 for my $track (@$tracks) {
72 $tracknum++;
73 if (!defined($track->{TITLE}) || scalar(@{$track->{TITLE}}) < 1) {
74 die("at least one TITLE required for track $tracknum")
75 }
76 $track->{ALBUM} = $album->{ALBUM};
77 $track->{TRACKNUMBER} = [$tracknum];
78 if (!defined($track->{ARTIST}) && defined($album->{ARTIST})) {
79 $track->{ARTIST} = $album->{ARTIST};
80 }
81 if (defined($date)) {
82 $track->{DATE} = [$date];
83 }
84 if (@discnumber) {
85 $track->{DISCNUMBER} = \@discnumber;
86 }
87 my $title = join(' ', @{$track->{TITLE}});
88 my $tracknum_s = two_digits($tracknum);
89 my $fn = join('/',
90 $dir,
91 join('_',
92 (map { two_digits($_) } @discnumber),
93 $tracknum_s,
94 mangle_for_file_name($title) . '.flac',
95 ),
96 );
97 -e $fn && die("cowardly refusing to clobber $fn");
98 my @pictures = ('--picture', quote('3|image/jpeg|||cover.front.jpeg')); # TODO optional
99 say(join(' ',
100 'flac -o',
101 quote($fn),
102 '--delete-input-file',
103 '-V',
104 '--no-padding',
105 '--best',
106 @pictures,
107 (map {
108 my $name = $_;
109 map {
110 ('-T', quote($name . '=' . $_))
111 } @{$track->{$_}}
112 } sort(keys(%$track))),
113 "track$tracknum_s.cdda.wav"
114 ));
115 }
116 say('rm tags cover.front.jpeg');
117
118 return 0;
119 }
120
121 if (!caller) {
122 exit(main(@ARGV))
123 }
124
125 1;