Es gibt bereits Fragen zur Beschleunigung eines Videos mit FFmpeg, wieDieses hier.
Meine Frage ist: Gibt es auch eine Möglichkeit, mehrere Abschnitte anzugeben, die über eine externe CSV beschleunigt werden sollen?
Meine CSV sieht folgendermaßen aus:
start, end
00:00:03.296, 00:00:14.372,
00:00:16.388, 00:00:33.635,
00:00:33.693, 00:00:39.428,
00:00:39.460, 00:00:50.355,
00:00:50.355, 00:01:17.892,
00:01:17.892, 00:01:19.845,
00:01:19.845, 00:01:47.616,
Dies sind die genauen Abschnitte (ein Abschnitt pro Zeile, zwei Zeitstempel, die den Anfang und das Ende jedes Abschnitts definieren), die um das Zehnfache beschleunigt werden sollen. Der Rest soll die ursprüngliche Wiedergabegeschwindigkeit beibehalten.
Gibt es eine Möglichkeit, dies zu tun?
Antwort1
Wir können den gewünschten PTS-Zeitstempel für jedes Videobild festlegen, indem wirsetztFilter mit ausführlichem verschachteltem if
Ausdruck.
Die folgende Antwort ist nur ein „Proof of Concept“, vorausgesetzt, Sie verfügen über das Wissen, um den komplexeren Ausdruck, den Sie benötigen, programmgesteuert zu erstellen. Die Lösung geht davon aus, dass das Eingabevideo eine feste Bildrate hat und dass es einfach ist, den Eingabezeitstempel aus der Eingabebildnummer zu berechnen.
Hinweis:
Durch das Beschleunigen von Teilen des Videos durch Festlegen der Zeitstempel wird ein Video mit variabler Bildrate (VFR) erstellt, das möglicherweise nicht auf allen Videoplayern gut wiedergegeben wird.
Es ist möglicherweise besser, ein Video mit fester Bildrate zu erstellen, indem Sie das gesamte Video um den Faktor 10 beschleunigen und jedes Bild 10 Mal in den Teilen der Originalrate duplizieren.
Beachten Sie, dass es relativ einfach ist, die Bilder mit einem Python-Skript zu duplizieren, das Bilder mit OpenCV liest und mit OpenCV schreibt (oder besser an FFmpeg weiterleitet).
Angenommen, wir haben die folgende Eingabedatei (40 Frames bei 1fps):
ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=40 -c:v libx264 -g 1 input.mp4
Die Zeitstempel des Eingabevideos sind:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
Angenommen, wir möchten im Bereich [0, 19] und [30, 39] beschleunigen und die folgenden Ausgabezeitstempel erhalten:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 21.1, 21.2, 21.3, 21.4, 21.5, 21.6, 21.7, 21.8, 21.9,
Wir können den folgenden FFmpeg-Befehl verwenden:
ffmpeg -y -r 100 -i input.mp4 -fps_mode:v passthrough -vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'" -c:v libx264 -g 1 output.mp4
-r 100
wird verwendet, um die Paketdauer auf 10 ms einzustellen (eine kurze Paketdauer ermöglicht eine höhere Auflösung der Zeitstempel).-fps_mode:v passthrough
- übergibt jedes Eingabebild vom Eingang an den Ausgang (ohne die Bilder aufgrund der Rate von 100 fps zu duplizieren).-vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'"
- Verwendetif
Ausdrücke und etwas Mathematik zum Anpassen der Zeitstempel.
Derif
Ausdruck gilt, wenn (Bedingung, Wert wenn wahr, Wert wenn falsch).
N
ist die Nummer des Eingabebilds, beginnen Sie bei Null zu zählen. setzt PTS für die ersten 10 Bilder
if(lt(N,10), N, ...
auf ... dividiert durch die Zeit in Sekunden durch die Zeitbasis.N
/TB
-g 1
- Setzen Sie die GOP-Größe zum Testen auf 1 (entfernen Sie sie). Dadurch bleibt das PTS bei Verwendung von FFprobe sortiert.
Überprüfen der Ausgabezeitstempel mit FFprobe:
ffprobe -select_streams v:0 -of default=noprint_wrappers=1 -show_entries packet=pts_time output.mp4
Die Ausgabe ist wie erwartet:
pts_time=0.000000
pts_time=1.000000
pts_time=2.000000
pts_time=3.000000
pts_time=4.000000
pts_time=5.000000
pts_time=6.000000
pts_time=7.000000
pts_time=8.000000
pts_time=9.000000
pts_time=10.000000
pts_time=10.100000
pts_time=10.190000
pts_time=10.300000
pts_time=10.400000
pts_time=10.500000
pts_time=10.600000
pts_time=10.700000
pts_time=10.800000
pts_time=10.900000
pts_time=11.000000
pts_time=12.000000
pts_time=13.000000
pts_time=14.000000
pts_time=15.000000
pts_time=16.000000
pts_time=17.000000
pts_time=18.000000
pts_time=19.000000
pts_time=20.000000
pts_time=21.000000
pts_time=21.100000
pts_time=21.200000
pts_time=21.300000
pts_time=21.400000
pts_time=21.500000
pts_time=21.600000
pts_time=21.700000
pts_time=21.800000
pts_time=21.900000
Animiertes GIF, das die Ausgabe demonstriert:
(Erstellt mit ffmpeg -y -i output.mp4 -filter_complex "[0:v]split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -r 1 output.gif
)