Open Source im professionellen Einsatz

Newsletter abonnieren
Seite durchsuchen

HEFTARCHIV | NEWS | E-BIBLIOTHEK | VIDEO | BLOGS | WHITEPAPER | EVENTS | ACADEMY | ABO | SHOP

user friendly

  Home  »  Heft & Abo  »  Heftarchiv  »  2010  »  01  »  Final Cut  

RSS-Feed der aktuellen News von Linux-Magazin Online Folgen Sie Linux-Magazin Online auf Twitter
Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark

Mencoder für Normalos

User, die zum ersten Mal auf Mencoder-Kommandos stoßen, wenden sich meist gleich entsetzt ab, denn scheinbar benötigen selbst einfachste Funktionen absurde Kombinationen von Optionen. Näher betrachtet ist die Bedienung aber nicht schwer: Um eine Videodatei in ein anderes Format umzuwandeln, nimmt Mencoder die erste Datei als erstes Argument entgegen, erwartet dann die Aktionen zur Umwandlung, gefolgt von der Option »-o«, der wieder die Ausgabedatei folgt:

mencoder input.avi Optionen -o output.avi

Ein Videostrom aus mehreren Eingangsdateien »input1.avi, input2.avi, ...« lässt sich ebenfalls sehr einfach erzeugen, indem der Benutzer die Dateinamen der Reihe nach auf der Kommandozeile hinschreibt.

Optionen für die Umwandlung teilen sich in Audio- und Videokomponenten auf. Um den Audiostrom der Eingangsdatei unverändert in die Ausgabedatei zu übernehmen, schreibt man »-oac copy« (a für Audio). Wer den Audio-Track stattdessen umkodieren möchte, schreibt »-oac pcm« für das PCM-Format oder »-oac mp3lame« für das mit dem Programm »lame« erzeugte MP3-Format. Braucht der verwendete Encoder noch Optionen wie zum Beispiel »vbr 3«, hängt der Benutzer sie im Mencoder-Aufruf unter der Option »-lameopts« an:

-oac mp3lame -lameopts vbr=3

Entsprechendes gilt für den Videoteil einer AVI-Datei. Um das Videoformat eins zu eins zu übernehmen, taugt »-ovc copy« (v für Video). Um das Videoformat in das Mjpeg-Format umzukodieren und dem verwendeten Encoder die Option »vcodec=mjpeg« mitzugeben, schreibt man »-ovc lavc -lavcopts vcodec=mjpeg«.

Perl automatisiert

Der Vorspann-Generator in Listing 2 nimmt drei Parameter entgegen: Die Videodatei, die er mit einem Titel versieht, und zwei Strings, die er als erste und zweite Zeile im Titelvideo unterbringt. Ruft man ihn mit

video-title-add testvideo.avi "Der Geek" U "Aufzucht und Hege"

Listing 2:
»video-title-add«

001 #!/usr/local/bin/perl -w
002 use strict;
003 use Sysadm::Install qw(:all);
004 use Imager;
005 use Imager::Fill;
006 use Log::Log4perl qw(:easy);
007 use Video::FrameGrab;
008 use File::Temp qw(tempdir tempfile);
009
010 sub shell;
011
012 my $title_length = 2; # length in seconds
013 my $FONT_FILENAME = "/usr/share/fonts/" .
014  "truetype/ttf-bitstream-vera/VeraSe.ttf";
015
016 Log::Log4perl->easy_init($ERROR);
017
018 my($video_file, $upper, $lower) = @ARGV;
019 die "usage: $0 ",
020   "video_file upper_text lower_text"
021   unless defined $upper;
022
023 (my $video_out = $video_file) =~
024         s/(.[^.]+$)/-withtitle$1/;
025
026 my $video_mum  = throwaway_file(".avi");
027 my $video_title = throwaway_file(".avi");
028 my $audio_title = throwaway_file(".wav");
029 my $audio_total = throwaway_file(".wav");
030
031 my $grabber = Video::FrameGrab->new(
032           video => $video_file);
033
034 my $meta = $grabber->meta_data();
035
036 my $height = $meta->{video_height};
037 my $width = $meta->{video_width};
038
039 my $dir = jpeg_dir_create(
040   $width, $height, $upper, $lower,
041   $meta->{video_fps} * $title_length);
042
043 shell qw(mencoder -nosound),
044    "mf://$dir/*.jpg",
045    qw(-mf fps=30 -o),
046    $video_title,
047    qw(-ovc lavc -lavcopts vcodec=mjpeg);
048
049 my $sample_size = $meta->{audio_bitrate} /
050 $meta->{audio_rate} /
051 $meta->{audio_nch} / 8;
052
053 silent_wav( $title_length, $audio_title,
054  $meta->{audio_rate}, $meta->{audio_nch},
055  $sample_size );
056
057 shell qw(mplayer -vc null -vo null -ao
058     pcm), $video_file;
059
060 shell "sox", $audio_title,
061    "audiodump.wav", "-o", $audio_total;
062
063 shell "mencoder", "-nosound", $video_title,
064    $video_file, qw(-ovc lavc -lavcopts
065    vcodec=mjpeg -o), $video_mum;
066
067   # add sound
068 shell "mencoder", $video_mum, qw(-oac copy
069    -audiofile), $audio_total,
070    qw(-ovc copy -o), $video_out;
071
072 ###########################################
073 sub throwaway_file {
074 ###########################################
075   my($suffix) = @_;
076
077   my($fh, $file) = tempfile(
078     UNLINK => 1,
079     SUFFIX => $suffix,
080   );
081   return $file;
082 }
083
084 ###########################################
085 sub shell {
086 ###########################################
087   my($stdout, $stderr, $rc) = tap @_;
088
089   if($rc) {
090     die "Command @_ failed: $stderr";
091   }
092 }
093
094 ###########################################
095 sub jpeg_dir_create {
096 ###########################################
097  my($w, $h, $upper, $lower, $n) = @_;
098
099  my $img = Imager->new(xsize => $width,
100             ysize => $height);
101
102  my $black = Imager::Color->new( 0,0,0 );
103  $img->box(color=> $black, filled => 1);
104
105
106  my $font = Imager::Font->new( file =>
107   $FONT_FILENAME) or die Imager->errstr;
108
109  $font->align(string => $upper,
110   size => 38, color => "white",
111   x => $width/2, y => $height/3,
112   halign => "center", valign => "center",
113   image => $img );
114
115  $font->align(string => $lower,
116   size => 38, color => "white",
117   x => $width/2, y => $height*2/3,
118   halign => "center", valign => "center",
119   image => $img );
120
121  my($dir) = tempdir( CLEANUP => 1 );
122
123  my $img_file = "$dir/c.jpg";
124
125  $img->write(file => $img_file) or
126   die "Cannot write ($!)";
127
128  for (1..$n-1) {
129    cd $dir;
130    (my $link = $img_file) =~ s/./$_./;
131    link $img_file, $link or die $!;
132    cdback;
133  }
134
135  return $dir;
136 }
137
138 ###########################################
139 sub silent_wav {
140 ###########################################
141  my($secs, $outfile, $rate, $channels,
142   $sample_size) = @_;
143
144  my($fh, $tempfile) =
145   tempfile( UNLINK => 1,
146        SUFFIX => ".dat" );
147
148  print $fh "; SampleRate $raten";
149  my $samples = $secs * $rate;
150
151  for (my $i = 0; ($i < $samples); $i++) {
152    print $fh $i / $rate, "t0n";
153  }
154  close $fh;
155
156  shell "sox", $tempfile, "-r", $rate,
157     "-u", "-$sample_size", "-c",
158     $channels, $outfile;
159 }

auf, erzeugt er eine neue AVI-Datei »testvideo-withtitle.avi«, die vor dem eigentlichen Video ein 2 Sekunden langes Titelfilmchen (Abbildung 2) enthält.


Abbildung 2: Der per Skript erzeugte Videovorspann läuft im Mplayer vor dem eigentlichen Video.

Das Skript ruft zunächst die ab Zeile 95 definierte Funktion »jpeg_dir_create()« auf, um »$n« gleiche Jpg-Bilder der Breite »$w« und der Höhe »$h« in einem temporären Verzeichnis zu erzeugen. Auf den Bildern sind die in »$upper« und »$lower« übergebenen Textzeilen auf schwarzem Hintergrund zu sehen. Insgesamt braucht ein 2-Sekunden-Video mit 30 Frames pro Sekunde genau 60 Bilder, also setzt das Hauptprogramm »$n« auf »60«.

Mit dem CPAN-Modul Imager erzeugt das Skript zunächst ein neues Imager-Bildobjekt mit den Maßen »$w« mal »$h«. Die gewünschte Farbe Schwarz definiert es über ein Objekt der Klasse Imager::Color. Der in der Variablen »$FONT_FILENAME« gespeicherte Pfad zeigt zu einer TTF-Datei mit dem gewünschten Font. Das neu erzeugte Font-Objekt bietet die Methode »align()« an, die einen ihr übergebenen String an einer definierten Stelle ins Bild malt.

Das mittels »write()« geschriebene Jpeg-Bild kommt in einem neu angelegten temporären Verzeichnis zu liegen. Die For-Schleife ab Zeile 128 erzeugt zu der eben angelegten Datei »c.jpg« noch weitere 59 Hardlinks, sodass Mencoder in Zeile 43 glaubt, 60 Dateien in einem Verzeichnis zu finden, obwohl es nur eine gibt. Der verwendete Codec ist »mjpeg«, da die kleine Nikon ihn nutzt und die Qualität des zusammengeleimten Videos leidet, falls man eine verlustreiche Kodierung in eine ebenfalls verlustreiche andere überführt.

Sie können diesen Artikel als PDF für 99 Cent kaufen. Klicken Sie dazu einfach auf eine der beiden Bezahloptionen Paypal oder ClickandBuy.


Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark
Ähnliche Artikel
Ordentlich in Bewegung Screencast-Software im Test
So Smart Nokias Linux-Handy N 900 im Test
Umzugshelfer Perl-Skript erleichtert Umzug der Sourcen von CVS nach Git
Das Log als Ohrwurm Perl-Skript realisiert das singende, klingende Internet
"New Code, old Culture" Gnome-Entwicklerkonferenz Guadec in Den Haag
Tooltipps Werkzeuge im Kurztest
Whitepaper
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele

Über die letzten Jahre hinweg haben sich Open Source Lösungen als fester Bestandteil des gesamten Datenintegrationsmarktes etabliert. Viele Unternehmen haben bereits das Open Source Modell für Ihre Datenintegrationsprojekte aufgegriffen. Das vorliegende White Paper illustriert anhand ausgewählter Fallstudien und Anwendungsbeispiele die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.

Download PDF (Registrierung erforderlich)
The Role of Open Source in Data Integration

Obwohl in den letzten Jahren viele technische Fortschritte erzielt werden konnten, verfügen die meisten Datenintegrationsprozesse nach wie vor nur über eine sehr begrenzte Automatisierung. Das vorliegende White Paper von dem Industry Analyst Mark Madson wird zunächst ein grundlegendes Verständnis von Daten Integration vermitteln, die Vorzüge von Open Source Lösungen für Daten Integration erläutern und Ihnen professionelle Empfehlungen geben, damit Sie Ihre Integrationsjobs noch einfacher und produktiver gestalten können.

Download PDF (Registrierung erforderlich)
Kommentare (1)
von
perle,
05.12.2009 17:33
Immer wieder....
... erstaunlich der Herr Schili