How to get subtitles using mencoder (Linux/BSD only)

Tutorials, tips and tricks.

Moderator: moderators

How to get subtitles using mencoder (Linux/BSD only)

Postby yostinso » Wed Mar 30, 2011 7:45 pm

This is a crosspost from the original thread here, but I think it's solid enough that it'll be widely useful.

Almost all the credit goes to badsanta, I just took his code and cleaned it up some. For one thing, it's much better at killing off mencoder as necessary now, and won't just kill every mencoder running (which is bad if you've got two streams going for whatever reason.)

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";


Edit 2011-03-30: Fixed bug in subtitle detection. (syntax error and bad quoting)[/b]
yostinso
 
Posts: 3
Joined: Wed Mar 30, 2011 5:32 pm

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby lucfig » Tue Oct 04, 2011 8:48 am

Does anyone know how to do this on Windows? Subtitles and seek are must have! :P
lucfig
 
Posts: 2
Joined: Tue Oct 04, 2011 7:32 am

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby valgarv » Mon Feb 06, 2012 5:43 pm

Hi,

thanks for the tip.

I've tried to implement this on a subsonic server but I keep getting a "Video not found or access denied etc" error in jwplayer.

No error is displayed in the subsonic log. I can see the TranscodeInputStream / InputStremReaderThread / InputStreamReaderThread mencoder_hook.pl "finished" lines.

I followed the instruction given in the comments (install mencoder, create .pl file, create symlink to mencoder and mkdir /var/subsonic/Pipes). Tried to change permissions (even tried some dirty 777) but nothing changed...

I had the same kind of trouble previously with ffmpeg (though it was displaying an error in subsonic log), but resolved it with a proper ffmpeg install + symlink in transcode folder.

If you have any advice I'd be grateful :D

EDIT : also, I tried it with several videos, which are working perfectly when i change config back to ffmpeg (except I don't get subtitles of course :mrgreen: ). Videos are all MKVs
valgarv
 
Posts: 3
Joined: Mon Feb 06, 2012 5:30 pm

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby jj123456 » Sun Feb 26, 2012 11:05 am

Hi all, I just started using subsonic, it's great by the way!

I was searching to how to do subtitle and found the post that discussed it. I tried the script but it didn't work for me.
The video will show but no subtitle comes out. After some research, I found the problem to be the -ass -sub option of the script, looks like mencoder doesn't like -ass <empty> -sub xxxx.srt, it needs to be either -ass xxxx.ass OR -sub xxxx.srt, not both at the same time.

I don't know if the version of mencoder I have or this is a bug in the script. But when I have .srt file, it will not show the subtitle. I don't have .ass subtitle to test, so I don't know. After much testing I found that if I take out the -ass option, then .srt will work, so I recommend either take the -ass line of the perl code or replace it w/ the follow perl codes.

Kinda lame change on my end, I'm sure a perl expert will code it better, but this seems to work for me. By the way, great job guys for solving this subtitle issue, I really appreciated it. Now if I can get .rm or .rmvb to work, then it'll be the perfect solution. Either way, the way it is right now, it's near perfect. Thanks all!

Code: Select all
foreach my $ext (".ass", ".srt") {
  my $subs = $file;
  $subs =~ s/\.[^\.]*$/$ext/;
  if (-e $subs) {
    if ($ext eq ".ass") {
       push @args, (
         "-ass", $subs,
         "-subpos", "95"
       );
    } else {
       push @args, (
         "-sub", $subs,
         "-subpos", "95"
       );
    }
  }
}
jj123456
 
Posts: 3
Joined: Sun Feb 26, 2012 10:36 am

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby jj123456 » Sun Feb 26, 2012 11:11 am

Well, not sure if you figured out the problem, but I noticed you created the /var/subsonic/Pipes with cap "P" instead of lower case "p". The perl script looks for the lowercase "pipes" directory. Unix is case sensitive, so it matters. Hope that fix your problem.

valgarv wrote:I followed the instruction given in the comments (install mencoder, create .pl file, create symlink to mencoder and mkdir /var/subsonic/Pipes). Tried to change permissions (even tried some dirty 777) but nothing changed...
jj123456
 
Posts: 3
Joined: Sun Feb 26, 2012 10:36 am

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby jj123456 » Sun Feb 26, 2012 12:50 pm

jj123456 wrote: Now if I can get .rm or .rmvb to work, then it'll be the perfect solution. Either way, the way it is right now, it's near perfect. Thanks all!


Kinda off the topic, but well, well, well ... I just got RMVB working ... haa haa :-)

Thanks guys, the mencoder solution helps with the conversion of rmvb to flv really well. RMVB just needed codecs in /usr/lib/codecs then it'll do the conversion. The codecs can be downloaded from the mplayer website. http://www.mplayerhq.hu/design7/dload.html

This is the perfect solution ... yay!
jj123456
 
Posts: 3
Joined: Sun Feb 26, 2012 10:36 am

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby valgarv » Thu Mar 01, 2012 12:43 pm

Hey, thanks for the help.

I did try the char case issue before actually posting... So was not coming from this.

Still have the issue (Video not found or access denied subsonic/stream?path......) and still can't find the source of the problem.

Code: Select all
[2012-03-01 13:09:54,132] DEBUG TranscodeInputStream - Starting transcoder: [/var/subsonic/transcode/mencoder_hook.pl] [0] [/media/movie.1080p.mkv] [1000k] [666] [360]

[2012-03-01 13:09:54,167] DEBUG InputStreamReaderThread - (/var/subsonic/transcode/mencoder_hook.pl) mencoder "/media/movie.1080p.mkv" "-v" "-ss" "0" "-of" "lavf" "-oac" "lavc" "-ovc" "lavc" "-lavcopts" "vcodec=flv:vbitrate=1000:acodec=libmp3lame:abitrate=96" "-srate" "44100" "-af" "lavcresample=44100" "-lavfopts" "format=flv" "-vf" "harddup,scale=666:-3" "-o" "/var/subsonic/pipes/4327.mencoder"

[2012-03-01 13:09:54,260] DEBUG InputStreamReaderThread - (/var/subsonic/transcode/mencoder_hook.pl) finished


Only thing I got from the subsonic log.

Also while checking syslog I could find this :

Code: Select all
[3802378.603504] mencoder[16096] trap divide error ip:6df939 sp:7fffd39c78a0 error:0 in mencoder[400000+a4e000]


This line appears each time I launch a video in subsonic. Tried reinstalling mencoder but nothing better.

Also if I try to encode a video using the commands called by the script I get a "Dimensions Not set / Floating point exception" from mencoder... So probably is the mencoder build faulty here, not the script implementation...

Code: Select all
mencoder "/media/movie.1080p.mkv" "-v" "-ss" "0" "-of" "lavf" "-oac" "lavc" "-ovc" "lavc" "-lavcopts" "vcodec=flv:vbitrate=1000:acodec=libmp3lame:abitrate=96" "-srate" "44100" "-af" "lavcresample=44100" "-lavfopts" "format=flv" "-vf" "harddup,scale=666:-3" "-o" "/var/log/test_mencoder.log"

.....
.....
........
Writing Header...
[flv @ 0x24c15e0] dimensions not set
Floating point exception

valgarv
 
Posts: 3
Joined: Mon Feb 06, 2012 5:30 pm

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby valgarv » Thu Mar 01, 2012 5:59 pm

OK nevermind it's actually working on AVI files (need to work out special characters -accents- display though). Problem is with MKVs so it should be coming from the mencoder parameters sent by the script.

EDIT : ok got everything working fine with AVI files, even accents in subtitles (added -utf8 option in the script). Still having the issue with MKVs, Mencoder doesn't seem to like MKV --> FLV transcoding, weird.

EDIT 2 : same error with mp4 file
valgarv
 
Posts: 3
Joined: Mon Feb 06, 2012 5:30 pm

Re: How to get subtitles using mencoder (Linux/BSD only)

Postby pestilent » Mon Sep 10, 2012 10:09 pm

When I set this up on my Subsonic server I do not get any video. Sound works fine and there are no errors in the logs, but the video is blank. So far I have tested with MKV and AVI files with the same results. Has anyone run into this? The encoding is soo much faster than ffmpeg, so I really want to get this working.
pestilent
 
Posts: 6
Joined: Thu Feb 10, 2011 9:31 pm


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 6 guests