Videos schneiden auf der Kommandozeile

Veröffentlicht am 10. January 2009

Besitzer einer TV-Karte oder eines an einen Receiver angeschlossenen Computers kennen sicher das Problem:
Da hat man nun endlich den lang erwarteten Film aufgezeichnet und möchte ihn für spätere Videoabende archivieren; doch leider ist er wie immer vollgestopft mit Werbung und es befinden sich mit etwas Pech auch noch die letzten zehn Minuten der vorherigen Sendung auf der Aufnahme, so dass die gemütliche Atmosphäre beim Filmabend durch ein lästiges Herumspulen bzw. -scrollen gestört wird.

Also muss Abhilfe geschafft werden:
ein Videoschnittprogramm kann die lästigen Teile, die nicht zum Film gehören, herausschneiden.

Glücklicherweise gibt es mittlerweile auch ausreichend viele Open-Source-Videoschnittprogramme, so dass diese Arbeit kostenneutral angegangen werden kann.

Ärgerlicher wird das ganze, wenn die Videodatei irgendwo auf einem Fileserver liegt, auf dem kein grafische Umgebung läuft – oder diese nicht erreichbar ist.

In diesem Falle muss man die Videodatei per Kommandozeile von ihrer ungewollten Werbe-Last befreien.
Wie dies mit ein paar Scripten und einem lokalen Mediaplayer zu bewerkstelligen ist, will ich hier kurz zeigen.

Zunächst ist es unumgänglich, sich eine lokale Kopie der Videodatei zu besorgen.
Dies ist nötig, um die Schnittstellen herauszufinden und den Schnittprozess zu kontrollieren.

Schritt 1: Finden der Schnittstellen (Cut marks)

Hierzu sollte man sich einen Block besorgen und mit einem Mediaplayer seiner Wahl (welcher in der Lage sein muss, zu scrollen und die aktuelle Zeitposition des Filmes anzuzeigen) den Film nach den Nahtstellen untersuchen.

Hierbei ist zu markieren, welche Zeitintervalle den Film enthalten.
Angenommen der Film startet bei 05:15 und endet bei 45:32 und es gibt eine Werbung von 13:56 bis 22:14, so sind die zu merkenden Zeitintervalle:
[05:15 - 13:56], [22:14 - 45:15]

Schritt 2: Umrechnen der Zeitkoordinaten in Sekunden

Als nächstes sollte man sich Gedanken machen, wie man den Film schneiden möchte.

Im Grunde gibt es hier zwei Möglichekeinen: Das Frame-basierte und das Sekunden-basierte Schneiden.

Ein Frame entspricht einem Einzelbild im Video. Daher ist das Frame-basierte Schneiden genauer, aber auch aufwendiger zu berechnen.

Ich möchte mich daher hier auf das Sekunden-basierte Schneiden beschränken.

Also, was zu tun ist: Die Zeitkoordinaten müssen in Sekunden umgerechnet werden (ganz normal: eine Minute sind 60 Sekunden, 1 Stunde sind 3600 Sekunden).
In diesem Beispiel ergibt das: [315 - 836], [1334 - 2715]

Leider benötigen die meisten Schnittprogramme statt der Endzeit der Fragmente deren Länge in Sekunden.
Daher berechnet man die Länge durch abziehen der Startzeit von der Endzeit:
[315, Länge 521], [1334, Länge 1381]

Schritt 3: Erzeugen der geschnittenen Fragmente

Um das Video nun zu bearbeiten, bieten sich verschiedene Programme an.
Nahezu jedes Abspielprogramm ist in der Lage, das abgespielte Video als Stream zu speichern.

Ebenso stellen viele Video-Bibliotheken (vlc, mplayer, ffmpeg, transcode) Mechanismen bereit, um Videostreams zu kürzen, umzukodieren oder zu filtern.

Da es für meine Zwecke als besonders geeignet erschien, habe ich mich für das Programm mencoder (“Movie Encoder”) des Videopaketes mplayer (http://www.mplayerhq.hu) entschieden.

Um nun, die beiden Fragmente des Films aus der Aufnahme zu isolieren, ist das Programm mencoder nun zweimal aufzurufen.

Dabei entspricht der Parameter -ss <Sekundenzahl> der Startposition des Fragments, der Parameter -endpos <Sekundenzahl> der Länge des Fragments und der Parameter -o <Outputdatei> gibt an, wohin das Ergebnis gespeichert werden soll.

Die beiden verbleibenden Parameter geben an, dass kein (zeitaufwendiges) umkodieren der Video- und Audiostreams gewünscht ist, sondern die vorhandenen Streams nur an der entsprechenden Stelle geschnitten werden sollen.

mencoder -ss 315 -endpos 521 -oac copy -ovc copy -o Film_Teil1.avi Aufnahme.avi
mencoder -ss 1334 -endpos 1381 -oac copy -ovc copy -o Film_Teil2.avi Aufnahme.avi

Schritt 4: Zusammenfügen der Fragmente

Im oben genannten Beispiel wird der Film durch einen Werbeblock getrennt, was dafür sorgt, dass der Film nun in zwei Teilen vorliegt.

Daher müssen die verschiedenen Fragmente nun wieder zu einem Video zusammengesetzt werden.
Hier bietet sich das Programm avimerge (Teil des Paketes transcode, https://bitbucket.org/achurch_/transcode/wiki/Home) an.

Dieses Programm ist geeignet mehrere Videos zu einem Video zusammenzusetzen. Als Parameter erwartet das Programm folgendes:

  • Der Parameter -o <Outputfile> gibt an, wohin das zusammengesetzte Video gespeichert werden soll
  • Der Parameter -i <Inputfile1> [<Inputfile2> [<Inputfile3> [...]]] gibt eine Liste von Teilvideos an, welche zusammengesetzt werden sollen

Um die (in diesem Fall) zwei Videodateien wieder zu einem Film zusammenzufügen, ist noch folgender Aufruf zu machen:

avimerge -o Film.avi -i Film_Teil1.avi Film_Teil2.avi

Schritt 5: Korrektur

Da die Zeitmarken der Abspielprogramme und der Schnittprogramme manchmal um ein oder zwei Sekunden auseinanderliegen, bietet es sich an, den fertig geschnittenen Film noch einmal an den Schnittbereichen zu untersuchen, ob der Film komplett ist und ob die Werbung komplett weggeschnitten wurde.
Andernfalls sind die Schritte 3 und 4 noch einmal mit leicht korrigieren Schnittkoordinaten durchzuführen, bis das Endergebnis den Ansprüchen genügt.

Schritt 6: Abschluss des Schnitts

Nachdem das lokale Video erfolgreich überarbeitet wurde, können nun dieselben Abweisungen auf das Ursprungsvideo auf dem entfernten System (bzw. Fileserver) per Kommandozeile losgelassen werden.
Ganz paranoide Manschen können auch mit geeigneten Hashwerten (md5sum) überprüfen, dass auf dem anderen System das gleiche Ergebnisvideo herauskam, wie auf dem lokalen System.

Wenn man nun zufrieden ist, kann man die temporären Videodateien (wie die Ursprungsaufnahme und die verschiedene Videofrgmente) löschen; der Schnittvorgang ist nun abgeschlossen.

Schritt 7: Automatisierung

Da die Schritte 2-4 weitestgehend vom Computer ausgeführt werden können, bietet es sich an, diesen Aufwand zu automatisieren.

Dazu habe ich folgendes PHP-Script geschrieben, welches die Schritte 2-4 vollautomatisch ausführt.

Es sind also nur die Schnittmarken aus Schritt 1 und ggf. die Korrektur aus Schritt 5 von Hand auszuführen.

Das Script wird folgendermaßen aufgerufen:

php cutvideo.php <Ursprungsdatei> <Zieldatei> <Zeitmarke1> [<Zeitmarke2> [...]]

Die Zeitmarken werden hierbei in der Form <Startzeit>-<Endzeit> eingegeben und jede Zeit hat endweder das Format <Sekunden> oder <Minuten>:<Sekunden> oder <Stunden>:<Minuten>:<Sekunden>.

In unserem Beispiel wäre also der Aufruf:

php cutvideo.php Aufnahme.avi Film.avi 05:15-13:56 22:14-45:15

Um das Script auszuführen, wird PHP mit Commandline-Interface (CLI) benötigt.

Download on Github

Kategorie: Linux
Schlagworte: