genaues Schneiden von Video (+ Audio) mit ffmpeg

10

Ich möchte, dass meine Website es Benutzern ermöglicht, ihre eigenen Clips aus einem von mir bereitgestellten Quellvideo genau zu erstellen.

Ich habe eine Quellvideodatei, die ich zuerst in eine für eine Website geeignete konvertieren möchte:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)

Ich benutze ffmpeg, um es so zu konvertieren:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4

Wenn ich mir dieses Video wieder ansehe, ist es qualitativ gut genug und klein genug für meine Bedürfnisse und lädt / spielt auf meiner Website.

Ich habe eine Webseite, auf der Benutzer einen Start- und Endpunkt für dieses Video auswählen und einen Clip erstellen können. Hier ist ein Beispiel für den Befehl ffmpeg, den ich dafür verwende:

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4

Das Problem ist, dass der Clip nicht immer zeitgenau genug ist. Normalerweise ist das Audio genau genug, aber das Video stoppt eine halbe Sekunde früher oder so.

Gibt es eine Möglichkeit, dies genau und synchron zu machen, um beispielsweise 0,2 Sekunden zu sagen?

EDIT: Hinzufügen -force_key_frames 00:00:00.2hat nicht geholfen.

BEARBEITEN: Ich habe den Ausschnitt so geändert, dass er -c:v libx264 -c:a aac -strict experimentalnicht -codec:v copy -codec:a copymit guten (ish) Ergebnissen verwendet wird.

Die Datei kann ohne Probleme extern wiedergegeben werden. Wenn ich sie jedoch in mein HTML5-Videoelement lade und wiedergebe, friert der letzte Teil des Videos (Audio ist in Ordnung) ein. Der letzte Teil, der einfriert, ist weniger als eine Sekunde lang.

Soll ich es mit einem anderen Video-Encoder versuchen? Was ist die beste Alternative für libx264? In Anbetracht dessen werde ich wahrscheinlich wollen, dass dies auf einer öffentlichen Website ist.

Aber Moment mal, deutet die Tatsache, dass es ohne Probleme mit einem Player wie MPC oder Windows Media Player genau wiedergegeben wird, nicht darauf hin, dass es sich um ein Problem mit Google Chrome oder dem HTML-Videoelement handelt? Oder verwende ich eine nicht unterstützte Codierung oder so?

Pete Oakey
quelle
Dies hat möglicherweise mit dem Timing der Keyframes zu tun. In jedem Fall sollte dies auf SuperUser.com verschoben werden.
Brad
Hallo, ffmpeg kann das Video zu keinem Zeitpunkt schneiden, es kann nur auf Keyframes schneiden; Aus diesem Grund ist Audio fast präzise, ​​Video nicht.
Kann ich es selbst bewegen? Ich werde versuchen, Keyframes zur Quelldatei mit -force_key_frames 00: 00: 00.2
Pete Oakey

Antworten:

9

Das Verhalten von -ssÄnderungen hängt davon ab, ob es als Eingabe- oder Ausgabeoption verwendet wird. Es ist häufig langsamer, kann jedoch bei Verwendung als Ausgabeoption genauer sein. Weitere Details und Beispiele finden Sie in der Antwort auf ffmpeg, das Videos aus einem bestimmten Zeitraum langsam konvertiert .

Um die Ausgabequalität zu ändern, source.mp4verwenden Sie die -crfOption mit einem Wert zwischen 18 und 28 (23 ist Standard). Beispiele finden Sie im Abschnitt CRF des FFmpeg- und x264-Codierungshandbuchs .

Ihr Trimmbefehl kann vereinfacht werden:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4

Ich habe ersetzt -codec:v copy -codec:a copydurch -c copy -map 0. Dadurch werden alle Streams anstelle nur der ersten Video- und Audio-Streams kopiert - obwohl die Eingabe aufgrund Ihres vorherigen Befehls nur zwei Streams enthält. Da Sie ohne Neucodierung nicht skalieren können und sich daher gegenseitig ausschließen -codec:v copyund Ihre Eingabe bereits auf die festgelegte Größe skaliert ist, habe ich die Filteroptionen entfernt.

Wenn es immer noch nicht genau genug ist, versuchen Sie:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4

Es wird langsamer sein, aber wahrscheinlich genauer. Unter den Links in der Antwort im ersten Link, den ich bereitgestellt habe, finden Sie eine Beschreibung der Unterschiede dieser beiden Beispiele.

Zuletzt sollten Sie source.mp4durchlaufen qt-faststart(befindet sich im Tools-Verzeichnis in der ffmpeg-Quelle) oder die -movflags faststartOption verwenden. Dadurch werden einige Daten an den Anfang der Datei verschoben, sodass die Wiedergabe beginnen kann, bevor sie vollständig heruntergeladen wird.

llogan
quelle
+1 für die Tipps, aber ich habe versucht, ffmpeg -i source.mp4 -ss 577.92 -t 011.980 -c copy -map 0 clip1.mp4 aber den ersten Teil (fast eine Sekunde) und den letzten Teil (vielleicht eine Viertelsekunde) des Video wird vermisst, Audio ist jedoch in Ordnung.
Pete Oakey
@PeteOakey Haben Sie versucht, ohne Bitstream-Kopie, aber tatsächliche Neucodierung zu schneiden?
Slhck
Versuchte es ohne Bitstream-Kopie - Ergebnisse an meine Frage angehängt.
Pete Oakey
3
Die Verwendung -ssals Ausgabeoption anstelle der Eingabeoption hat mein Problem behoben: Das erste Videobild war im Ausgabevideo ungefähr 1 Sekunde lang, nur Audio davor (ebenfalls bestätigt durch ffprobe -show_frames). Wenn Sie sich -ssdanach bewegen -i, werden Audio- und Videobilder ab Bild 0
ausgegeben