]>
diplodocus.org Git - flac-archive/blob - fa-flacd
8 B<fa-flacd> - archive CDs to single FLAC files
12 B<fa-flacd> [B<-j> I<jobs>] [B<-v>]
20 use Getopt
::Long
qw(:config gnu_getopt no_ignore_case);
21 use POSIX
':sys_wait_h';
30 $verbose and print(STDERR
$_) for @_;
33 # Return the ARTIST, ALBUM, and DATE followed by a list of all the
34 # lines in the file FN.
43 verbose
("Opening tags file $fn\n");
44 open(TAGS
, $fn) or die("open($fn): $!");
49 ($tag, $value) = split(/=/, $_, 2);
53 verbose
("ARTIST $artist from $fn\n");
56 verbose
("ALBUM $album from $fn\n"); # cperl-mode sucks "
59 close(TAGS
) or die("close($fn): $!");
61 return ($artist, $album, @tags);
64 # Process the fa-rip output in the directory DIR.
73 verbose
("Renaming $dir/tags\n");
74 rename("$dir/tags", "$dir/using-tags")
75 or die("rename($dir/tags, $dir/using-tags): $!");
77 ($artist, $album, @tags) = get_tags
("$dir/using-tags");
79 verbose
("mkdir($artist)\n");
80 -d
$artist or mkdir($artist) or die("mkdir($artist): $!");
82 verbose
("chdir($dir)\n");
83 chdir($dir) or die("chdir($dir): $!");
88 verbose
("Running flac\n");
89 $status = system('flac', '-o', "../$artist/$outfile.flac-tmp",
90 '--delete-input-file', '-V', '--cuesheet',
91 'cue', '--no-padding', '--best',
92 map({ ('-T', $_) } @tags),
94 if (WIFEXITED
($status)) {
95 if (($status = WEXITSTATUS
($status)) != 0) {
96 die("flac exited with status $status");
98 } elsif (WIFSIGNALED
($status)) {
99 die("flac killed with signal ", WTERMSIG
($status));
100 } elsif (WIFSTOPPED
($status)) {
101 die("flac stopped with signal ", WSTOPSIG
($status));
103 die("Major horkage on system(flac): \$? = $? \$! = $!");
106 verbose
("Cleaning up $dir\n");
107 unlink('using-tags') or die("unlink(using-tags): $!");
108 unlink('cue') or die("unlink(cue): $!");
109 rename('log', "../$artist/$outfile.log")
110 or die("rename(log, ../$artist/$outfile.log): $!");
111 chdir('..') or die("chdir(..): $!");
113 rename("$artist/$outfile.flac-tmp", "$artist/$outfile.flac")
114 or die("rename($artist/$outfile.flac-tmp, $artist/$outfile.flac): $!");
116 if (-x
"$dir/post-processor") {
117 verbose
("Running './$dir/post-processor $artist/$outfile.flac'\n");
118 system("./$dir/post-processor", "$artist/$outfile.flac");
119 unlink("$dir/post-processor") or die("unlink($dir/post-processor): $!");
122 rmdir($dir) or die("rmdir($dir): $!");
130 while (($pid = waitpid(-1, WNOHANG
)) > 0) {
131 push(@finished, [$pid, $?]);
134 $SIG{CHLD
} = \
&reaper
;
143 if (not defined($pid)) {
148 if ($debug or $pid == 0) {
149 $SIG{CHLD
} = 'IGNORE';
150 open(STDERR
, ">$dir/log") or die("open(STDERR, >$dir/log): $!");
154 verbose
("new job $pid for $dir\n");
164 $pid = $finished[$i][0];
165 $status = $finished[$i][1];
167 verbose
("$pid finished (");
168 if (WIFEXITED
($status)) {
169 verbose
('exited with status ', WEXITSTATUS
($status));
170 } elsif (WIFSIGNALED
($status)) {
171 verbose
('killed with signal ', WTERMSIG
($status));
172 } elsif (WIFSTOPPED
($status)) {
173 verbose
('stopped with signal ', WSTOPSIG
($status));
177 for ($j = 0; $j <= $#jobs; $j++) {
178 $pid == $jobs[$j] and splice(@jobs, $j, 1) and last;
181 splice(@finished, $i, 1);
190 $SIG{CHLD
} = \
&reaper
;
192 if (scalar(@jobs) <= $MAXJOBS) {
193 foreach $i (glob('*/tags')) {
194 push(@jobs, newjob
(dirname
($i))) <= $MAXJOBS or last;
198 for ($i = 0; $i <= $#finished; $i++) {
202 verbose
(scalar(@jobs), " jobs\n");
213 'debug|X' => \
$debug,
214 'jobs|j=i' => \
$jobs,
215 'verbose|v' => \
$verbose,
216 'help|h|?' => \
$help,
218 $help and pod2usage
(-exitstatus
=>0, -verbose
=>1);
228 B<fa-flacd> and B<fa-rip> together comprise B<flac-archive>, a system
229 for archiving audio CDs to single FLAC files. B<fa-flacd> is the guts
230 of the system. It runs in the directory where the audio archives are
231 stored, scanning for new ripped CDs to encode and rename; it never
232 exits. B<fa-rip> generates the inputs for B<fa-flacd>: the ripped WAV
233 file, Vorbis tags, and a cuesheet.
235 Both programs expect to be run from the same directory. They use that
236 directory to manage directories named by artist. Intermediate files
237 are written to temporary directories here. B<fa-flacd> processes the
238 temporary directories into per-album files in the artist directories.
240 Every 5 seconds, B<fa-flacd> scans its current directory for
241 directories with a file called "tags" and creates a processing job for
242 each one. The number of jobs B<fa-flacd> attempts to run is
243 controlled by the B<-j> option and defaults to 4. B<fa-flacd> will
244 print diagnostic output when the B<-v> option is given.
246 A processing job first renames the directory's "tags" file to
247 "using-tags" so that B<ra-flacd> will not try to start another job for
248 this directory. This file is left as is when an error is encountered,
249 so a new job will not be started until the user corrects the error
250 condition and renames "using-tags" back to "tags". Next, it encodes
251 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
252 and "using-tags" for Vorbis tags. Any diagnostic output is saved in
253 the "log" file. Finally, B<fa-flacd> moves the "cue" and "log" files
254 to the artist directory (named by album) and removes the temporary
257 If the temporary directory contains an executable file named
258 "post-processor", B<fa-flacd> executes that file with the relative
259 path to the output FLAC file as an argument. The output files are in
260 their final location when "post-processor" starts. Possible uses are
261 running B<flac2mp3>, moving the output files to a different location,
262 removing the lock file, or adding to a database. The standard input,
263 output, and error streams are inherited from B<fa-flacd>, so they may
264 be connected to anything from a tty to /dev/null. This means that you
265 may want to redirect these streams, if you want to save them or do any
272 =item B<-j> [B<--jobs>] I<jobs>
274 Run up to I<jobs> jobs instead of the default 4.
276 =item B<-v> [B<--verbose>]
278 Print diagnostic information.
284 Written by Eric Gillespie <epg@pretzelnet.org>.
286 flac-archive is free software; you may redistribute it and/or modify
287 it under the same terms as Perl itself.
292 # cperl-indent-level: 4
293 # perl-indent-level: 4
294 # indent-tabs-mode: nil
297 # vi: set tabstop=4 expandtab: