2017-04-10 4 views
0

Der ffmpeg CLI ermöglicht es Ihnen, -r <fps> oder -vf fps=<fps> anzugeben, um einen festen FPS für Ihren Ausgang festzulegen.ffmpeg: Reduzieren Sie fps wenn über dem Schwellenwert, aber nicht erhöhen wenn unter dem Schwellenwert

Das Verhalten Ich mag würde bekommen, ist:

  • Eingang beliebige FPS haben kann (wahrscheinlich 20-120).
  • Wenn der FPS-Eingang> 30 ist, reduzieren Sie ihn auf 30 FPS.
  • Wenn der FPS-Eingang < = 30 ist, ändern Sie FPS nicht.

Weiterer Kontext:

Vorgenannte Optionen sind große Videos auf einen festen FPS zu normalisieren, aber nicht so gut, dass Videos machen effizient eine bestimmte FPS Schwelle nicht verwinden. In der Tat, wenn ich -r 30 und das Video ist 29 fps, ffmpeg wird uns eine Menge CPU, um es auf 30 zu erhöhen, wenn es nicht für meinen Anwendungsfall benötigt wurde.

Antwort

1

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 
Verwandte Themen