Files
handbrake-cluster/handbrake-cluster-worker.pl
Ben Roberts 4f7fd4307a Fixed bug in title selection
Typo caused the title options to be ignored, and so longest title only
was being ripped.
2010-02-17 09:27:56 +00:00

174 lines
4.7 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);
}
close($child_out);
# If the rip process failed, report an error status here
waitpid($child_pid, 0);
my $child_exit_status = $? >> 8;
if (!$child_exit_status) {
$log->warning("Ripping process returned error status: $child_exit_status");
return undef;
}
$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