Bildervorschau aus einem Video erstellen
Mit den Videoplayer mplayer und der Toolsammlung ImageMagick lässt sich schnell die eigene Videovorschau gestalten.
Informationen des Videos
Das Beispielvideo soll test.avi heißen.
Mit dem Befehl
mplayer -nosound -vo null -endpos 1 -really-quiet -identify test.avi
erhält man Informationen über das Video, z.B.
ID_VIDEO_ID=0 ID_AUDIO_ID=0 ID_CLIP_INFO_NAME0=major_brand ID_CLIP_INFO_VALUE0=mp42 ID_CLIP_INFO_NAME1=minor_version ID_CLIP_INFO_VALUE1=0 ID_CLIP_INFO_NAME2=compatible_brands ID_CLIP_INFO_VALUE2=isommp42 ID_CLIP_INFO_NAME3=creation_time ID_CLIP_INFO_VALUE3=2012-03-01 17:26:17 ID_CLIP_INFO_N=4 ID_FILENAME=test.avi ID_DEMUXER=lavfpref ID_VIDEO_FORMAT=H264 ID_VIDEO_BITRATE=322452 ID_VIDEO_WIDTH=640 ID_VIDEO_HEIGHT=480 ID_VIDEO_FPS=25.000 ID_VIDEO_ASPECT=1.3333 ID_START_TIME=0.00 ID_LENGTH=165.28 ID_SEEKABLE=1 ID_CHAPTERS=0 ID_VIDEO_CODEC=ffh264 ID_EXIT=EOF
Bilder extrahieren
Ebenfalls mit mplayer lassen sich Bilder aus dem Video extrahieren, z.B. mit
mplayer -nosound -really-quiet -ss 3 -vo jpeg -speed 99 -vf framestep=270 test.avi
Beginnend ab der 3 Sekunde (-ss 3) des Videos wird jedes 270. Bild (framestep=270) als JPEG im gleichen Verzeichnis unter fortlaufender Nummer ( 00000001.jpg, 00000002.jpg, 00000003.jpg, ... , 99999999.jpg) gespeichert. Durch die Informationen kann man sich sinnvolle Angaben ausrechnen. Das Beispielvideo enthält ID_LENGTH * ID_VIDEO_FPS = 165.28 * 25 = 4125 Bilder insgesamt. Um 15 Vorschaubilder zu erhalten werden die ersten 75 Bilder (3 Sekunden mit je 25 Bildern) abgezogen und durch 15 dividiert. So erhält man die Angabe für framestep= 270.
Je nach Länge und Auflösung des Videos, sowie der Hardware-Ausstattung kann dies einige (viele) Minuten dauern.
Bilder beschriften
Mit dem zur ImageMagick Sammlung gehörenden mogrify kann man Bilder beschriften. Der Name des Videos kann so auf jedem Vorschaubild sichtbar gemacht werden:
mogrify -fill white -stroke black -gravity SouthEast -font Helvetica-Bold -pointsize 72 -draw "text 0,0 'Video test.avi'" 000000??.jpg
Der Text wird weiß (-fill white) mit schwarzem Rand (-stroke black) unten rechts (-gravity SouthEast) eingeblendet. Schriftgröße (-pointsize 72) und Schriftart (-font Helvetica-Bold) kann man ebenfalls angeben.
Bilder zusammenfügen
Ebenfalls zu ImageMagick gehört montage mit dem sich die 15 einzelnen JPEGs zu einem großen Bild zusammensetzen lassen:
montage 000000??.jpg -tile 3x5 -geometry +0+0 test_preview.jpg
Die Bilder werden in 3 Spalten und 5 Zeilen (-tile 3x5) angeordnet. Das erste Bild wird oben links (+0+0) eingefügt und nicht skaliert.
Mit dieser Methode könnte man auch eine Galerie-Vorschau erstellen.
Vorschau Bild skalieren
Für eine einheitliche Größe, z.B. einer Breite von 500 Pixeln sorgt wieder das Tool mogrify:
mogrify -resize 500 test_preview.jpg
Automatisierung
Für die automatische Erstellung sorgt dieses kleine PHP-Script:
<?php
#!/usr/bin/env php
<?php // Bezeichnung der Videodatei, wird als Parameter uebergeben,
// z.B. vidprevpic.php test.avi
$movie = escapeshellcmd($argv[1]);
// Sekunden, die zu Beginn des Videos uebersprungen
// werden sollen
$start = 30;
// Anzahl der gesamten Vorschau-Bilder
$shot= 18;
// Diretory zum Speichern der Vorschaubilder
$pwd = escapeshellcmd($_SERVER['PWD']);
// Ausfuehrbare Dateien definieren
$mplayer = exec('which mplayer');
$mogrify = exec('which mogrify');
$montage = exec('which montage');
// Informationen holen; Laenge und Anzahl der Bilder pro Sekunde speichern
$exec = $mplayer
. ' -nosound'
. ' -really-quiet'
. ' -ss ' . $start
. ' -vo null'
. ' -endpos 1'
. ' -identify ' . escapeshellarg($movie)
. ' 2?>&1';
$sol = exec($exec, $out);
if(is_array($out)) {
foreach($out as $i) {
list($var,$val) = explode("=", $i, 2);
switch ($var) {
case 'ID_LENGTH': // Laenge des Videos
$length = intval($val);
break;
case 'ID_VIDEO_FPS': // Bilder pro Sekunde
$fps = intval($val);
break;
}
}
}
// Script beenden, wenn ein Paramter fehlt
if (empty($fps) or empty($length)) {
die ("Movie paramters not found\n");
}
// Gesamte Anzahl der Bilder im Video
$frames = $fps * $length;
// Schrittweite der Frames in Anzahl
$fstep = intval(($frames - ($start * $fps)) / $shot);
// Schrittweite der Frames in Sekunden
$tstep = ($length - $start) / $shot;
// Liste aller Vorschaubilder
$rmfiles = '';
// Vorschaubilder erzeugen
$exec = $mplayer
. ' -nosound'
. ' -really-quiet '
. ' -ss ' . $start
. ' -vo jpeg:quality=90:outdir=' . $pwd
. ' -speed 99'
. ' -vf framestep=' . $fstep
. ' ' . $movie;
exec($exec);
// Die Position des Bildes als Stunden:Minute:Sekunde Angaben
// in jedes Bild schreiben
for ($i=0; $i 3600) ? gmdate("H:i:s", $t) : gmdate("i:s", $t) ;
if (is_file($file)) {
// Liste der Vorschaubilder generieren
$rmfiles .= " " . $file;
// Zeitangabe unten rechts platzieren
$exec = $mogrify
. " -resize 160"
. " -fill white"
. " -stroke black"
. " -gravity SouthEast"
. " -font Helvetica-Bold"
. " -pointsize 14"
. " -draw \"text 0,0 '" . $d . "'\""
. " " . $file;
system($exec);
}
else {
die ($file . " not found");
}
}
// Dateiname fuer das Vorschaubild generieren:
$parts = pathinfo($movie);
$preview = $parts['filename'] . ".jpg";
// Das zusammengesetzte Vorschau-Bild generieren ...
exec ( $montage . " $rmfiles -tile 3x" . intval($shot/3) . " -geometry +0+0 " . escapeshellarg($pwd) . "/" . escapeshellarg($preview));
// Aufraeumen: Alle Vorschaubilder loeschen
system ("rm" . $rmfiles);
?>