Manche Dienste akzeptieren nur Dateien bis zu einer bestimmten Größe – sei es ein E-Mail-Anhang, ein Messenger oder ein Upload-Portal. Ist ein Video zu groß, bleibt oft nur das Aufteilen in mehrere Teile.
In diesem Beitrag zeigen wir, wie sich Videodateien mit ffmpeg in kleinere Stücke zerlegen lassen – ohne zeitaufwendiges und qualitätsminderndes Neuencodieren. Neben dem manuellen Weg stellen wir ein Bash-Script vor, das die Aufteilung anhand einer gewünschten Maximalgröße vollständig automatisiert. Für Fälle, in denen das Video als eine Datei erhalten bleiben soll, zeigen wir am Ende des Beitrags außerdem, wie sich die Größe durch ein Neuencodieren reduzieren lässt.
- Voraussetzungen
- Der manuelle Weg
- Das Problem bei der Aufteilung nach Größe
- Der automatisierte Ansatz
- Funktionsweise
- Anwendung
- Einschränkungen
- Alternative: Komprimieren durch Neuencodieren
- Fazit
Voraussetzungen
Vorausgesetzt wird ein Linux-System mit installiertem ffmpeg beziehungsweise ffprobe. Unter Debian und Ubuntu genügt dafür folgendes Paket:
1 | sudo apt install ffmpeg |
Die weiteren vom Script genutzten Werkzeuge awk und stat sind auf üblichen Linux-Systemen bereits vorhanden.
Der manuelle Weg
ffmpeg kann ein Video an einer beliebigen Zeitposition teilen. Die beiden wichtigen Optionen dafür sind -ss für den Startpunkt und -t für die Dauer des Ausschnitts. Entscheidend ist der Parameter -c copy: Dabei werden die vorhandenen Video- und Audiostreams unverändert kopiert, anstatt sie neu zu encodieren. Das ist um ein Vielfaches schneller und geht ohne Qualitätsverlust vonstatten.
Ein Video, das an der Position von 50 Minuten geteilt werden soll, lässt sich zum Beispiel so in zwei Teile zerlegen:
1 | ffmpeg -ss 0 -i grosses-video.mp4 -t 00:50:00 -map 0 -c copy teil1.mp4 |
Der erste Befehl erzeugt teil1.mp4 vom Anfang bis zur Marke von 50 Minuten, der zweite Befehl teil2.mp4 mit dem Rest. Mit -map 0 werden alle Streams der Quelldatei übernommen – also auch zusätzliche Tonspuren oder Untertitel. Der Wert für -ss und -t kann wahlweise im Format HH:MM:SS oder als Sekunden angegeben werden.
Beide Teile lassen sich alternativ auch mit einem einzigen Befehl erzeugen:
1 | ffmpeg -i grosses-video.mp4 -t 00:50:00 -map 0 -c copy teil1.mp4 \ |
Hinweis
Durch -c copy kann ffmpeg nur an sogenannten Keyframes schneiden. Liegt an der gewünschten Schnittstelle kein Keyframe, verschiebt sich der tatsächliche Schnitt zum nächsten Keyframe. Die Teile können dadurch minimal länger oder kürzer ausfallen als angegeben.
Das Problem bei der Aufteilung nach Größe
Das manuelle Vorgehen funktioniert gut, wenn die Schnittpositionen in etwa bekannt sind. Soll dagegen eine maximale Dateigröße pro Teil eingehalten werden, wird es aufwendig: Die Dateigröße hängt von der Bitrate ab, und diese schwankt über die Laufzeit des Videos. Aus der gewünschten Größe lässt sich daher nur eine grobe Schätzung für die Schnittdauer ableiten – ob ein Teil am Ende wirklich unter dem Limit bleibt, weiß man erst nach dem Erzeugen.
Genau dieses Problem löst das folgende Script.
Der automatisierte Ansatz
Das folgende Script split-video.sh teilt eine Videodatei automatisiert in möglichst gleich große Teile, die jeweils unter einer vorgegebenen Maximalgröße bleiben:
1 |
|
Funktionsweise
Das Script geht dabei folgendermaßen vor:
- Maximalgröße abfragen: Nach dem Start wird interaktiv die gewünschte Maximalgröße pro Teil in MB abgefragt (muss größer als 10 sein). Als Zielgröße wird bewusst konservativ 10 MB unter diesem Maximum angesetzt, um Puffer für schwankende Bitraten zu haben.
- Schätzung der Schnittdauer: Über
ffprobeundstatwerden Dauer und Größe der Quelldatei ermittelt. Aus der durchschnittlichen Bitrate wird eine initiale Schnittdauer berechnet. - Teile erzeugen: Für jeden Teil wird ffmpeg mit
-ss,-tund-c copyaufgerufen. Die Ausgabe erfolgt zunächst in ein temporäres Verzeichnis. - Größenprüfung mit Wiederholung: Wird ein Teil zu groß, wird die Schnittdauer proportional zum Überschuss reduziert – inklusive eines zusätzlichen Puffers von fünf Prozent – und der Versuch wiederholt. Nach 20 erfolglosen Versuchen bricht das Script ab.
- Fortschreibung anhand der tatsächlichen Dauer: Da bei
-c copynur an Keyframes geschnitten werden kann, kann die erzeugte Datei von der angeforderten Dauer abweichen. Der Startpunkt des nächsten Teils wird deshalb aus der perffprobegemessenen tatsächlichen Dauer des erzeugten Teils berechnet – nicht aus der angeforderten. - Abschlusskontrolle: Am Ende wird die Summe der Teildauern mit der Originaldauer verglichen und bei einer Abweichung von mehr als einer Sekunde eine Warnung ausgegeben.
- Verschieben der Ergebnisse: Erst wenn alle Teile erfolgreich erstellt wurden, werden sie als
<name>_Teil<N>.<endung>neben der Quelldatei abgelegt. Existiert eine Zieldatei bereits, bricht das Script ab, statt sie zu überschreiben.
Anwendung
Das Script wird ausführbar gemacht und mit der Videodatei als Argument aufgerufen:
1 | chmod +x split-video.sh |
Eine beispielhafte Ausgabe sieht wie folgt aus:
1 | Maximale Dateigröße pro Teil in MB: 500 |
Einschränkungen
Da das Script weiterhin -c copy verwendet, kann ffmpeg nur an geeigneten Keyframes schneiden. Die gemessene Dauer eines Teils ist daher nicht unter allen Umständen identisch mit dem exakten Zeitbereich in der Quelldatei. Trotz der Fortschreibung anhand der tatsächlichen Dauer kann es zu kleinen Überlappungen oder Lücken zwischen den Teilen kommen.
Die Größenbegrenzung ist dagegen bewusst konservativ ausgelegt: Geprüft wird gegen die Zielgröße, also 10 MB unter dem eingestellten Maximum. Sollte sich ein Teil wegen der Keyframe-Struktur nicht klein genug schneiden lassen – etwa wenn bereits ein einzelner Keyframe-Bereich die Zielgröße übersteigt –, bricht das Script ab, statt eine zu große Datei als erfolgreich auszugeben. In diesem Fall ließe sich das Video nur durch ein Neuencodieren mit verkürztem Keyframe-Intervall oder eine geringere Bitrate weiter verkleinern.
Alternative: Komprimieren durch Neuencodieren
Das Aufteilen ist nicht immer gewünscht – etwa wenn das Video als eine zusammenhängende Datei weitergegeben oder abgespielt werden soll. In diesem Fall lässt sich die Dateigröße auch durch ein Neuencodieren reduzieren. Im Gegensatz zum Kopieren der Streams wird das Video dabei komplett neu kodiert, was deutlich länger dauert und je nach Einstellung mit einem sichtbaren Qualitätsverlust einhergeht.
Für die Kodierung mit dem weit verbreiteten Encoder libx264 steuert der Parameter -crf (CRF) die Qualität beziehungsweise die resultierende Dateigröße. Der CRF-Wert liegt zwischen 0 und 51, wobei kleinere Werte für eine bessere Qualität bei größeren Dateien stehen. Werte um 18 gelten als nahezu verlustfrei wahrnehmbar, Werte ab etwa 28 zeigen je nach Inhalt bereits deutliche Kompressionsartefakte. Der Standardwert von libx264 liegt bei 23.
Ein einmaliger Aufruf zum Komprimieren einer Datei sieht zum Beispiel so aus:
1 | ffmpeg -i grosses-video.mp4 -vcodec libx264 -crf 25 grosses-video_komprimiert.mp4 |
Auch hierfür gibt es ein Script, das den Aufruf vereinfacht:
1 |
|
Das Script compress-video.sh wird wie das Aufteilungs-Script mit der Videodatei als einzigem Argument aufgerufen und fragt interaktiv den gewünschten CRF-Wert ab (Standard: 25). Das Ergebnis wird als <name>_komprimiert.mp4 neben der Quelldatei abgelegt; eine bereits vorhandene Zieldatei wird nicht überschrieben. Nach der Kodierung zeigt das Script die Größen von Original und Ergebnis sowie die prozentuale Ersparnis an:
1 | chmod +x compress-video.sh |
1 | CRF-Wert (Standard 25, kleiner = bessere Qualität): 25 |
Da die tatsächliche Ersparnis stark vom Videoinhalt und den vorhandenen Codecs abhängt, empfiehlt sich gegebenenfalls ein Testlauf mit einem kurzen Ausschnitt, bevor eine große Datei komplett neu kodiert wird.
Fazit
Für das schnelle Aufteilen großer Videodateien ist ffmpeg mit -c copy das Werkzeug der Wahl: kein Neuencodieren, kein Qualitätsverlust und in Sekundenschnelle fertig. Wer die Teile nach einer festen Uhrzeit schneiden möchte, kommt mit einzelnen ffmpeg-Befehlen aus. Soll dagegen eine Maximalgröße eingehalten werden, nimmt split-video.sh die iterative Anpassung der Schnittdauer automatisch vor – inklusive Größenprüfung und Abschlusskontrolle der Gesamtdauer.
Muss das Video dagegen als eine Datei erhalten bleiben, führt kein Weg am Neuencodieren vorbei. Hier hilft compress-video.sh, das die Kodierung mit libx264 und einem wählbaren CRF-Wert übernimmt – mit dem unvermeidlichen Nebeneffekt längerer Laufzeit und möglichem Qualitätsverlust.