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"
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.
| 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)
|
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links"
nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedrucken Fassung entsprechen.
|
perle,
05.12.2009 17:33