Gastbeitrag von pit und akli
Der Urlaub ist vorbei. Auf dem Smartphone jede Menge kurze Video Clips: Der Handstand am Pool, der Hund mit der Frisbee Scheibe, irgendwas mit Katzenbabys. Jedes für sich ganz nett, aber erst zusammengesetzt die perfekte Erinnerung an eine gute Zeit. Stellt sich nur die Frage, wie sich eine unbestimmte Zahl von kurzen Videos so einfach wie möglich zusammenschneiden lässt und zwar so, dass das Ergebnis auch gefällt. Es gibt auch für Linux herausragende Videoschnittprogramme. Wer damit noch nie gearbeitet hat, muss sich auf eine steile Lernkurve einstellen. Das muss doch auch anders gehen.
Projekt: Videos zusammenfügen
Anfang des Jahres hatte sich akli (einer der Autoren dieses Beitrags) gefragt, ob sich nach dem Betrachten eines Videos im Browser dessen Datei-Fragmente im Cache so rekonstruieren lassen, dass am Ende das ursprüngliche Original zur Verfügung steht. In Folge entstand ein Einzeiler [1] mit dem sich das Vorhaben bequem umsetzen ließ. Die beiden Autoren fragten sich, ob es möglicherweise eine Schnittmenge zwischen diesem Projekt und dem eingangs beschriebenen Vorhaben gäbe. Schnell war klar, dass ein simpler Einzeiler nicht mehr ausreichen würde.
Also warum nicht ein Script schreiben, das alle Videos innerhalb des ausgewählten Verzeichnisses in eines zusammenführt, wobei Clip 1 von schwarz ein-, das letzte Video nach schwarz aus- und alle Clips dazwischen überblendet werden sollten.
Autor pit nutzt für aufwändigere Schnittprojekte die grafische Anwendung kdenlive, die letztlich zum Rendern auf ein Video Framework namens melt aufsetzt.
In Debian beschreibt apt show melt
die Anwendung wie folgt:
Medienplayer und Videoeditor für die Befehlszeile. melt war als Testwerkzeug für das MLT-Rahmenwerk gedacht, ist jedoch auch ein mächtiger Mehrspur-Videoeditor für die Befehlszeile. Es kann auch als minimalistischer Medienplayer für Audio- und Videodateien verwendet werden.
Melt selbst ist eine reine CLI-Anwendung, für die es eine ausgezeichnete Dokumentation gibt [4]. Howtos oder Tutorials zur direkten Verwendung von Melt sind im Netz aber kaum zu finden. Nach intensiver Lektüre der Dokumentation und mehreren Stunden ausprobieren funktionierte schließlich der manuelle Programmaufruf, der zum beschriebenen Ziel führte.
Grobes Prinzip:
melt einblenden > VIDEO1 > überblenden > VIDEO2 … VIDEOx > ausblenden … rendere nach OUTFILE
Frisch ans Werk
Der passende Befehl für ein Beispiel mit drei Videos lautet:
melt colour:black out=30 \
01.mp4 -mix 30 -mixer luma -mixer mix:-1 \
02.mp4 -mix 30 -mixer luma -mixer mix:-1 \
03.mp4 -mix 30 -mixer luma -mixer mix:-1 \
colour:black out=30 -mix 30 -mixer luma -mixer mix:-1 \
-profile hdv_720_30p \
-consumer avformat:$(date +%y%m%d-%H%M%S)-videomix.mp4 \
vcodec=libx264 b=2M acodec=aac ab=96k
Das ließe sich auch in ein Script packen – unter der Voraussetzung, dass es immer exakt drei Videos mit exakt diesen Namen sind. Gewünscht war aber ein Script, das mit beliebig vielen Videos zurechtkommt. An dieser Stelle waren aklis Erfahrungen beim Erstellen von Shell-Scripts gefragt.
Teamwork
Nach einer Anfrage im Forum von siduction [2] entstand ein nur wenige Zeilen umfassendes Script, das prinzipiell das Gleiche leistete, wie das oben beschriebene Beispiel. Eine pfiffige Schleife stellte darüber hinaus aber sicher, dass beliebig viele Video-Clips verarbeitet werden. Ihr ahnt, wie lang, unübersichtlich und fehleranfällig ein solcher Programmaufruf wäre, müsste man ihn manuell eingeben.
Versuch Nummer 1
#!/bin/bash
#Name: multivideo.sh
OUTPUT="melt colour:black out=$FRAMES"
for i in *.mp4; do
OUTPUT="$OUTPUT $i -mix $FRAMES -mixer luma -mixer mix:-1";
done
OUTPUT="$OUTPUT colour:black out=$FRAMES -mix $FRAMES -mixer luma -mixer mix:-1";
exec $OUTPUT -profile hdv_1080_25p -consumer avformat:$(date +%y%m%d-%H%M%S)↵
-videomix.mp4 vcodec=libx264 b=2M acodec=aac ab=96k
Eine Bemerkung zu den Dateinamen: Die for
-Schleife liest alle Dateien mit der Erweiterung .mp4 ein und sortiert sie nach ihrem Namen – Ziffern zuerst, dann Buchstaben. Wir machen uns dieses Verhalten zunutze und vergeben Namen mit vorangestellten zwei- oder dreistelligen Ziffern. Ist man sich bei der Sichtung der Videos nicht sicher, ob doch noch das ein oder andere hinzukommt, lässt man in der Ziffernfolge einfach Lücken. Die for
-Schleife kann damit problemlos umgehen.
Da geht noch was …
Eigentlich war das Ziel erreicht: Das Script erledigte zuverlässig die gestellte Aufgabe, konnte mit einer beliebigen Anzahl von Videos umgehen und ersparte die Arbeit mit einer GUI. Pit – ausgestattet mir nur rudimentären Kenntnissen in Sachen Scripting – hatte zwei weitere Feature Requests, die sich beim manuellen Programmaufruf auch schnell umsetzen ließen:
Melt versteht sich auf die unterschiedlichsten AV-Formate. Die Beschränkung auf mp4-Dateien war also eigentlich nicht nötig. Eine zweite Erweiterung sollte es möglich machen, dem Script die Dauer für das Ein-, Über- und Ausblenden als optionalen Parameter übergeben zu können.
Erweiterung des Scripts
Ersteres lässt sich sehr einfach bewerkstelligen: In der for
-Schleife wurde *.mp4
durch $(ls)
ersetzt, da Melt fast alle Audio- und Videoformate und Codecs unterstützt, die FFmpeg für die Eingabe verwendet [3]. Außerdem wird das Script auf einen eigens dafür vorgesehenen Ordner angewendet, der ausschließlich Videos mit vorangestellten Ziffern im Dateinamen enthält. Die Interpolation durch $(ls)
liefert die gewünschte Liste der Dateinamen.
Für die zweite Erweiterung sorgt eine am Anfang ergänzte case
-Anweisung. Wird dem Aufruf für die Anzahl der Überblend-Frames eine ganzzahlige Dezimalzahl als Option mitgegeben, verwendet das Script diesen Wert. Fehlt die Option, erfolgt die Überblendung mit 30 Frames.
Das finale Script
Nur vier zusätzliche Zeilen und eine kleine Änderung reichen aus, um das Script universeller einsetzbar zu machen. Ausführliche Beschreibungen der Befehle und Optionen schließen sich an.
#!/bin/bash
#Name: multivideo.sh
case $1 in
''|[!0-9]) FRAMES="30" ;;
*) FRAMES="$1" ;;
esac
OUTPUT="melt colour:black out=$FRAMES"
for i in $(ls); do
OUTPUT="$OUTPUT $i -mix $FRAMES -mixer luma -mixer mix:-1";
done
OUTPUT="$OUTPUT colour:black out=$FRAMES -mix $FRAMES -mixer luma -mixer mix:-1";
exec $OUTPUT -profile hdv_1080_25p -consumer avformat:$(date +%y%m%d-%H%M%S)-videomix.mp4
Erläuterungen zu den melt-Parametern:
colour:black out=30
Erstellt einen komplett schwarzen Clip, Länge = 30 Bilder (frames)01.mp4 -mix 30 -mixer luma -mixer mix:-1
Überblendet 01.mp4 mit dem vorherigen Clip (Video- und Audiospur) Die Parameter sind für alle folgenden Clip gleich. Lediglich der Dateiname ändert sich.-mix 30 -mixer luma
Teil für die Video-Überblendung (30 frames)-mixer mix:-1
Teil für die Audio-Überblendung
colour:black out=30 -mix 30 -mixer luma -mixer mix:-1
colour:black out=30
Erstellt am Ende einen komplett schwarzen Clip,-mix 30 -mixer luma -mixer mix:-1
zu dem vom vorherigen Clip ausgeblendet wird.
-profile
Dieser Parameter steuert, welches Format (Auflösung, Bildrate) die Ausgabedatei hat. Der Aufruf melt -query “profiles” gibt über die möglichen Formate Auskunft.-consumer
Der Parameter steuert, wohin melt „produziert“. Im Script ist das eine mp4-Datei und es wird festgelegt, welche Codecs und Bitraten für Audio und Video verwendet werden.
Erläuterungen zu den bash Befehlen
- Zeilen 3 – 6. Die
case
-Anweisung in Zeile 4 testet, ob die Variable 1 leer ist ( ‘’ ) oder ( | ) ob sie andere Zeichen als die Ziffern 0 bis 9 ( [!0-9] ) enthält. In diesem Fall wird der Standardwert von 30 Frames für das Ein-, Über- und Ausblenden verwendet. Im anderen Fall kommt Zeile 5 zum Zug und übernimmt den im Aufruf angegebenen Wert für die Frames. - Zeilen 8 – 12, die Variable
$OUTPUT
und diefor
-Schleife In die Variable schreiben wir die bereits oben erwähnten melt-Parameter. Zuerst die Einblendung, dann erhält die Schleife mit$(ls)
die sortierte Liste der Videos und generiert für jedes die Überblendung und am Schluss folgt die Ausblendung. - Zeilen 14,
exec
-Anweisung: Hier wird die Variable$OUTPUT
mit den ergänzenden melt-Parametern anexec
übergeben und von der bash ausgeführt.
Links
- [1] Projekt Videostreams zusammensetzen
- [2] Hilferuf im Forum – mit Antwort
- [3] Unterstützte AV Formate
- [4] melt Dokumentation
- [5] FAQ
Foto Credits: Anton Darius on Unsplash