Dies kann mit Video mit konstanter Bildrate erfolgen - meine unten beschriebene Methode funktioniert möglicherweise bei VFR-Video, aber ich habe kein geeignetes Video zum Testen.
Grund Befehl:
ffmpeg -i 120.mp4 -vf "select='eq(n,0)+if(gt(t-prev_selected_t,1/30.01),1,0)'" -vsync 0 out.mp4
Auf einem 120 fps Strom,
Video: h264 (High) ... 120 fps, 120 tbr, 15360 tbn, 240 tbc
diese
Video: h264 (High) ... 30.08 fps, 30 tbr, 15360 tbn, 240 tbc
produziert Was die Auswahlfilter funktioniert, nach dem ersten Frame der Auswahl ist nur Wählen Sie weitere Bilder aus, wenn ihr Abstand vom zuvor ausgewählten Bild 1/30 Sekunde oder mehr beträgt. In der Praxis werden dadurch Videos auf unter 30 fps dezimiert.
Zwei Dinge zu beachten:
1) die Dauer des letzten Rahmens abgeschnitten wird, so dass der fps
Wert, der etwas größer sein wird als das Ziel. Aber alle anderen Bilder laufen mit 30 fps.
2) Die Ausgabe-Framerate ist die höchste Zahl, die durch Division der Quellrate durch eine ganze Zahl erhalten wird. Wenn also in dem Befehl 30.01
durch 26
ersetzt wird, wird das Ergebnis 24 tbr
sein, da weder 25 noch 26 erhalten werden können, indem 120 durch eine ganze Zahl dividiert wird. Dies hat den Vorteil, Bewegungsstottern in der Ausgabe zu vermeiden. Der Divisor in dem Befehl sollte geringfügig größer als die Decke sein, d. H. 30.01
anstelle von 30
. Sonst sind die Ergebnisse wackelig.
Wenn die Eingabe 30 fps oder weniger beträgt, werden alle Bilder ausgewählt.
Addendum:
Wenn der Ausgang des obigen Befehl an eine andere Instanz ffmpeg geleitet wird, fps
die Ausgabe ist exakt und der Codec-Rate tbc
wird ebenfalls zurückgesetzt.
ffmpeg -i 120.mp4 -vf "select='eq(n,0)+if(gt(t-prev_selected_t,1/30.01),1,0)'" -vsync 0
-c:v rawvideo -c:a pcm_s16le -f nut - | ffmpeg -f nut -i - out.mp4