Alle geraden oder ungeraden Frames mit FFmpeg löschen?

14

Gibt es eine genaue Möglichkeit, Rohvideos aufzunehmen und daraus ein neues Video zu extrahieren, das nur ungerade oder gerade Frames enthält (nach Wahl)?

Beispielsweise:

Ich habe "blah.yuv" mit 400 Bildern (0-399). Ich möchte "blahOdd.yuv" mit den Frames 1-399 (1,3,5,7 ... 399) und "blahEven" mit den Frames 0-398 (0,2,4,6 ... 398) erstellen ).

Irgendwelche Ideen, wie man es nur mit FFmpeg macht?

Kennzeichen
quelle

Antworten:

11

Um genau zu arbeiten, konvertieren Sie das Video zuerst in einen RAW YUV-Bitstream (sofern dies nicht bereits geschehen ist).

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

Nächster Schritt: Der selectFilter nimmt einen Ausdruck , wobei ndie Bildnummer ist.

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

Um ffmpegFrames nicht zu duplizieren, müssen Sie die Hälfte der Framerate Ihrer Eingabe erzwingen - also setzen Sie "2" als Eingabe und "1" als Ausgabe. Vergessen Sie nicht, das WxH durch die tatsächlichen Abmessungen Ihres Clips zu ersetzen, da der unformatierte Bitstream keinen Header hat, der diese Informationen enthält.

Stattdessen besteht eine andere Möglichkeit darin, den setptsFilter hinzuzufügen , um neue Zeitstempel für die Ausgabe festzulegen. Aber sei vorsichtig, da es Frames nicht genau fallen lässt. Hier ist 25 die tatsächliche gewünschte Ausgangsbildrate:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv

Sie können natürlich ein anderes (beliebiges ffmpeg -pix_fmts) Pixelformat auswählen . Stellen Sie sicher, dass Sie beim Lesen der Datei die Pixelgröße und das Pixelformat kennen:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …
slhck
quelle
Danke, für neue Versionen von FFMPEG sollte es -vf anstelle von -filter sein: v. Außerdem sollte es mod (n-1 \, 2) sein, da die Anzahl n von 1 zu beginnen scheint, während die Anzahl der Bilder von 0 zu beginnen scheint (ansonsten wird das erste Bild dreimal dupliziert). Es gibt jedoch immer noch ein Problem: Es dupliziert die Frames, während ich sie entfernen möchte. Der endgültige Clip enthält beispielsweise nur die Hälfte der Frames.
Mark
-vfist ein Alias ​​von -filter:v. Ich kann es jetzt nicht zuverlässig testen, werde es aber später untersuchen, wenn ich wieder auf meinem Computer bin. Vielleicht kann der tinterlaceFilter das auch?
Slhck
Ich habe versucht, '-r 2 -i blah.yuv -r 1', aber es zeigt mir einen Fehler Option Framerate nicht gefunden.
Mark
Ah sorry .. Scratch that, das funktioniert nicht (mehr?) Und nur für Bilder.
Slhck
1
@AnmolSinghJaggi Nein, dies löscht nur Frames, aber ich wäre mir nicht sicher, ob es so deterministisch ist (dh, löscht jeden ungeraden Frame). Es basiert auf Zeitcodes, die möglicherweise nicht genau sind.
Slhck
2

Wenn Ihr ffmpeg mit der AviSynth-Flagge erstellt wurde, können Sie meiner Meinung nach eine .avsDatei übergeben.

Sie können dies überprüfen, indem Sie die Konfigurationsdaten ausführen ffmpegund suchen . --enable-avisynth--enable-avisynth

Wenn es dort können Sie es gerne nutzen so: ffmpeg -i blahEven.avs blahEven.yuv.

Wo blahEven.avsist einfach:

ffvideosource ("blah.yuv"). SelectEven ()

Verwenden Sie für ungerade Bilder SelectOdd().

Weitere Informationen zur Verwendung finden Sie in der SelectEvery- Dokumentation.

Louis
quelle
Dies ist eine ausgezeichnete Alternative, aber wie ich bereits erwähnt habe - ich darf nur ffmpeg verwenden. Der Grund dafür ist, dass es Teil eines automatisierten Systems ist, das nur .bat-Dateien erstellt, keine Möglichkeit zum Hinzufügen von AVS.
Mark
@Mark Ich dachte, wenn --enable-avisynthda wäre, würde das bedeuten, dass AviSynth in ffmpeg eingebaut ist, aber da bin ich mir nicht sicher.
Louis