This version also supports seeking so you can watch your video from the middle, and lets you add additional options via the subsonic config page. It will also use either .srt or .ass subtitles, as available.
See the usage information at the top of the script for how to install and use. If you're running Subsonic on Linux, this should be easy-peasy. If someone wants to write instructions for using this with Cygwin on Windows, please do!
- Code: Select all
#!/usr/bin/perl
# mencoder_hook.pl
# Perl hook script for using mencoder to encode FLV with Subsonic
# Renders subtitles if they exist in the same dir and with the same name as
# the video and end in either .ass or .str
# Usage:
# Install mencoder (apt-get install mencoder)
# Paste this script into mencoder_hook.pl in /var/subsonic/transcode/
# Create a link to mencoder: ln -s /usr/bin/mencoder /var/subsonic/transcode/mencoder
# Create the folder /var/subsonic/pipes
# Go to the "Transcoding" config in Subsonic
# Edit "mp4 > flv" (and any other video->flv encoders that you want)
# Set "Step 1" to:
# mencoder_hook.pl %o %s %bk %w %h
# Enjoy!
# If you are having trouble with video/audio sync issues, try adding "-mc 1", e.g.:
# mencoder_hook.pl %o %s %bk %w %h -mc 1
# If you are getting the wrong audio track, use "-aid #", where # is the audio track number (they start at 1), e.g.:
# mencoder_hook.pl %o %s %bk %w %h -aid 2
use strict;
use POSIX qw(mkfifo);
my ($start_offset, $file, $bitrate, $width, $height, @user_args) = @ARGV;
$bitrate =~ s/k$//;
my $pipe = sprintf("/var/subsonic/pipes/%04d.mencoder", int(rand(10000)));
mkfifo( $pipe, 0770 ) or die "Couldn't make pipe";
my @args = (
$file,
"-ss", $start_offset,
"-of", "lavf",
"-oac", "lavc",
"-ovc", "lavc",
"-lavcopts", "vcodec=flv:vbitrate=" . $bitrate . ":acodec=libmp3lame:abitrate=96",
"-srate", "44100",
"-af", "lavcresample=44100",
"-lavfopts", "format=flv",
"-vf", "harddup,scale=$width:-3",
"-o", $pipe
);
foreach my $ext (".ass", ".srt") {
my $subs = $file;
$subs =~ s/\.[^\.]*$/$ext/;
if (-e $subs) {
push @args, (
"-ass",
"-sub", $subs,
"-subpos", "95"
);
}
}
open OLDOUT, ">&", \*STDOUT;
open OLDERR, ">&", \*STDERR;
my $child = fork();
if (!$child) {
# CHILD
$SIG{'TERM'} = sub { syslog("info", "TERMED CHILD"); };
print STDERR "mencoder " . join(" ", map { "\"$_\"" } @args, @user_args) . "\n";
open STDOUT, ">", "/dev/null";
open STDERR, ">", "/dev/null";
exec("mencoder", @args, @user_args);
}
# PARENT
$SIG{'TERM'} = sub {
# Kill mencoder with a SIGKILL so it actually quits
kill 'KILL', $child;
unlink $pipe;
print STDERR "killed prematurely; child was $child\n";
};
# Print the pipe to stdout
open F, "<", $pipe or print STDERR "Pipe is missing!\n";
my $buf;
my $oldout = select(OLDOUT); $| = 1; select($oldout);
while (read F, $buf, 1024) {
print OLDOUT $buf;
}
print STDERR "finished\n";