Videos zusammenschneiden: Script oder GUI?

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 die for-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 an exec übergeben und von der bash ausgeführt.
Zusammenschnitt aus 15 Videos mit Melt

Links

Foto Credits: Anton Darius on Unsplash

Teilt den Beitrag, falls ihr mögt

Abonnieren
Benachrichtige mich bei
11 Kommentare
Most Voted
Newest Oldest
Inline Feedbacks
View all comments