Dienstag, 10. November 2009

Batch-Encoding für Video-Streaming

Videos im Internet bereitzustellen ist mittlerweile nicht mehr schwer, Youtube und Konsorten machens möglich. Wenn man aber selbst Hand anlegen möchte, dann muss man sich erstmal durch den Formatedschungel kämpfen und dann noch den passenden Transkoder dazu finden. Eine plattformübergreifende Lösung ist der "mencoder", ein Kommandozeilen-Utility des Pakets MPlayer. Der "mencoder" de- und enkodiert mittlerweile alle gängigen Videoformate - wenn man denn die richtigen Kommandozeilenparameter kennt.
Da ich den MPlayer mittlerweile auch auf meine Nokia N810 installiert habe, wollte ich einfach mal ein paar meiner Videos umkodieren, um sie auf diesem Gerät anschauen zu können. Und da ich viele Videos, aber nur ne 8GB-Speicherkarte habe, sollten die Videos auf meinem Webserver liegen, und per Videostream aufgerufen und abgespielt werden können. Für das Streaming gibt es mittlerweile ein Haufen Formate, ich habe mich letztendlich für eine ASF-Container mit MPEG4-Stream entschieden. Nach verschiedenen Versuchen hat sich für das N810 eine Bitrate von 250 kbps und eine Auflösung von 320xXXX als günstig erwiesen. Mit einem 2pass-encoding ist die Qualität dann auch ordentlich.
Als letztes Problem erwies sich das Transkodieren von WMV-Dateien. Dieser Post half mir auf die Sprünge: die Option "-ofps 23.976" tuts dann auch für dieses Format. Letztendlich sehen meine Aufrufe des "mencoder" dann so aus, wenn man ein WMV als Ausgangsdatei hat (für andere Formate dann eben ohne "-ofps 23.976"):

mencoder -vf scale -zoom -xy 320 -oac mp3lame -lameopts abr:br=48 -srate 22050 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=250:autoaspect:vhq:keyint=15:vpass=1 -of lavf -lavfopts format=asf -ofps 23.976 -o /dev/null infile.wmv
mencoder -vf scale -zoom -xy 320 -oac mp3lame -lameopts abr:br=48 -srate 22050 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=250:autoaspect:vhq:keyint=15:mbd=2:trell:vpass=2 -of lavf -lavfopts format=asf -ofps 23.976 $additional_parameters -o outfile.asf infile.wmv

Der erste Aufruf schreibt eine temporäre Datei "divx2pass.log", die auf keinen Fall gelöscht werden darf. Erst der zweite Aufruf erzeugt dann die Datei, deswegen eben "2pass-encoding". Und da ich wie gesagt einen Berg Videos hier habe, habe ich mir ein kleines Perl-Skript geschrieben, das mir alle Videos in einem Verzeichnis der Reihe nach umwandelt. Das Verzeichnis wollte ich dem Skript gleich auf der Kommandozeile übergeben. Das Skript prüft alle Dateien im Verzeichnis auf die Dateiendung, gefundene Videodateien werden dann in ein Unterverzeichnis "asf" transkodiert:

#!/usr/bin/env perl
use File::Spec;

my $dir = $ARGV[0];
my $videorate = 250;
my $audiorate = 48;
my $videosize = 320;

die "arg 1 muss das verzeichnis sein." unless $dir;

my @fileendings = ( "avi", "mpg", "mpeg", "wmv", "mp4", "asf" );

opendir(DIR, $dir);
my @files = readdir(DIR);
# . und .. entfernen
shift @files; shift @files;
closedir(DIR);

chdir($dir);
mkdir('asf') unless (-d 'asf');

foreach $file(@files) {
my $ending = '';
foreach $_(@fileendings) { $ending = $_ if $file =~ m/\.$_$/; }
next if $ending eq '';
$asffile = $file;
$asffile =~ s/\.$ending$/.asf/;
$asffile = File::Spec->catfile('asf', $asffile);
next if (-f $asffile);
my $additional_parameters = "";
if ($ending eq "wmv") {
$additional_parameters = "-ofps 23.976";
}
print "Start: $file nach $asffile\n";
`mencoder -vf scale -zoom -xy $videosize -oac mp3lame -lameopts abr:br=$audiorate -srate 22050 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$videorate:autoaspect:vhq:keyint=15:vpass=1 -of lavf -lavfopts format=asf $additional_parameters -o /dev/null \"$file\"`;
`mencoder -vf scale -zoom -xy $videosize -oac mp3lame -lameopts abr:br=$audiorate -srate 22050 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$videorate:autoaspect:vhq:keyint=15:mbd=2:trell:vpass=2 -of lavf -lavfopts format=asf $additional_parameters -o \"$asffile\" \"$file\"`

}

Das Skript kann einfach mit in der Kommandozeile mit "perl batchencode.pl " gestartet werden. Die Werte für die Bitraten und die Videogröße könnt ihr über die Variablen natürlich beliebig ändern.

1 Kommentare:

Anonym hat gesagt…

vielen dank. inspieriert mich!

Kommentar veröffentlichen