Files
handbrake-cluster/handbrake-cluster-worker.pl
Ben Roberts 3ea5aa5706 Batch processing and config file support
Added a config file to describe multiple jobs to run, and to provide
values for options not specified on command line.
In the config file, presets can be used to save duplication of rip
options common to multiple jobs.
2010-02-17 01:13:58 +00:00

164 lines
4.4 KiB
Perl
Executable File

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Gearman::Worker;
use Getopt::Long;
use IPC::Open2;
use Log::Handler;
use Pod::Usage;
use String::Random qw/random_string/;
use Storable qw/thaw/;
# Handle interrupts, and term signals
$SIG{'INT'} = 'INT_handler';
$SIG{'TERM'} = 'TERM_handler';
# Globals
our %options = (
verbose => 0,
quiet => 0,
log_file => '/tmp/handbrake-cluster-worker.log',
silent => 0,
help => 0,
pretend => 0,
job_servers => ['build0.sihnon.net', 'build1.sihnon.net', 'build2.sihnon.net'],
handbrake => '/usr/bin/HandBrakeCLI',
);
Getopt::Long::Configure( qw(bundling no_getopt_compat) );
GetOptions(
'verbose|v+' => \$options{verbose},
'debug|d' => \$options{debug},
'quiet|q' => \$options{quiet},
'silent|s' => \$options{silent},
'log|l=s' => \$options{log_file},
'help|h' => \$options{help},
'pretend|n' => \$options{pretend},
'job-servers|j=s@' => \$options{job_servers},
'handbrake' => \$options{handbrake},
) or pod2usage(-verbose => 0);
pod2usage(-verbose => 1) if ($options{help});
# Setup logging
my $log = Log::Handler->new();
my $maxLogLevel = ($options{debug} ? 'debug' : ($options{quiet} ? 3 : $options{verbose} + 4)); # default to logging warning+, unless quiet in which case log error+, or debug in which case log everything
my $maxFileLogLevel = ($options{debug} ? 'debug' : 'info');
if ( ! $options{silent}) {
$log->add(
screen => {
log_to => 'STDOUT',
minlevel => 'emergency',
maxlevel => $maxLogLevel,
},
);
}
if ( $options{log_file}) {
$log->add(
file => {
filename => $options{log_file},
minlevel => 'emergency',
maxlevel => $maxFileLogLevel,
},
);
}
# Setup the worker, and listen for jobs
my $worker = Gearman::Worker->new(job_servers => $options{job_servers});
$worker->register_function(rip => \&do_rip);
$worker->work while 1;
sub do_rip {
my $job = shift;
my %rip_options = %{ thaw($job->arg) };
$log->notice("Beginning new rip to $rip_options{output_filename}");
my $uuid = random_string('cccccc');
$log->debug("Using $uuid as unique identifier for this job");
my $rip_filename = $rip_options{output_filename};
$rip_filename =~ s/\.([^\.]+)$/\.$uuid\.$1/;
# Generate deinterlace options
my @deinterlace_options;
push @deinterlace_options, '-d' if ($rip_options{deinterlace} == 1);
push @deinterlace_options, '-5' if ($rip_options{deinterlace} == 2);
my @title_options;
if ($rip_options{title} < 0) {
push @title_options, '-L';
} else {
push @title_options, '-t', $rip_options{title};
}
# Generate the command line for handbrake
my @handbrake_cmd = (
'nice', '-n', $rip_options{nice},
$options{handbrake},
'-i', $rip_options{input_filename},
'-o', $rip_filename,
@title_options.
'-f', $rip_options{format},
'-e', $rip_options{video_codec},
'-q', $rip_options{quantizer},
'-w', $rip_options{video_width},
'-l', $rip_options{video_height},
@deinterlace_options,
'-a', $rip_options{audio_tracks},
'-E', $rip_options{audio_codec},
'-A', $rip_options{audio_names},
'-s', $rip_options{subtitle_tracks},
);
$log->debug("Beginning ripping process with command:\n" . join(' ', @handbrake_cmd));
# Execute the ripping process
my ($child_in, $child_out);
my $child_pid = open2($child_out, $child_in, @handbrake_cmd);
# Don't need to write from the child
close($child_in);
my $line;
while ($line = <$child_out>) {
$log->debug($line);
}
$log->notice("Finished rip to $rip_filename");
return $rip_filename;
}
sub INT_handler {
$log->error("Caught interrupt, exiting.");
exit 0;
}
sub TERM_handler {
$log->error("Caught SIGTERM, exiting.");
exit 0;
}
__END__;
=head1 NAME
handbrake-cluster-worker - Processes DVD rips farmed out by gearman
=head1 SYNOPSIS
handbrake-cluster-worker.pl -h
handbrake-cluster-worker.pl [-v [-d]|-q|-s]
[-l logfile]
[-n]
=head1 DESCRIPTION
Processes ripping tasks as requested by a gearman job server. Logging and the
job servers to use are configurable by command line arguments.
=head1 OPTIONS
=cut