Czy upuszczać każdą parzystą lub nieparzystą klatkę za pomocą FFmpeg?

14

Czy istnieje dokładny sposób pobrania surowego wideo i wyodrębnienia z niego nowego filmu, który zawiera tylko nieparzyste klatki, a nawet klatki (z wyboru)?

Na przykład:

Mam „blah.yuv” z 400 ramkami (0–399). Chcę utworzyć „blahOdd.yuv”, który zawiera ramki 1-399 (1,3,5,7 ... 399) i „blahEven”, który zawiera ramki 0-398 (0,2,4,6 ... 398 ).

Wszelkie pomysły, jak to zrobić, używając tylko FFmpeg?

znak
źródło

Odpowiedzi:

11

Aby działać poprawnie, najpierw przekonwertuj wideo na strumień bitów RAW YUV (jeśli jeszcze nie jest):

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

Następny krok: selectfiltr przyjmuje wyrażenie , gdzie njest numer klatki.

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

Aby ffmpegnie powielać klatek, musisz wymusić połowę liczby klatek na sekundę na wejściu - więc ustawisz „2” jako wejście, a „1” na wyjście. Nie zapomnij zastąpić WxH rzeczywistymi wymiarami klipu, ponieważ surowy strumień bitów nie ma nagłówka, który przenosi te informacje.

Zamiast powyższego inną możliwością byłoby dodanie setptsfiltra w celu ustawienia nowych znaczników czasu dla danych wyjściowych. Ale bądź ostrożny, ponieważ nie wyświetla dokładnie klatek. Tutaj 25 to rzeczywista liczba klatek na sekundę, którą chcesz:

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

Możesz oczywiście wybrać inny format pikseli (dowolny ffmpeg -pix_fmts). Upewnij się, że podczas czytania pliku znasz rozmiar i format pikseli:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …
slhck
źródło
Dzięki, W przypadku nowych wersji FFMPEG powinno być -vf zamiast -filter: v. Ponadto powinien to być mod (n-1 \, 2), ponieważ liczba n wydaje się zaczynać od 1, a liczba klatek od 0 (w przeciwnym razie pierwsza ramka jest powielana 3 razy). Ale nadal istnieje problem, który powiela klatki, a ja chcę się ich pozbyć - np. Ostatni klip będzie zawierał tylko połowę klatek.
Mark
-vfjest pseudonimem -filter:v. Nie mogę teraz wiarygodnie go przetestować, ale przyjrzę się temu później, kiedy wrócę na maszynę. Może tinterlacefiltr może zrobić to samo?
slhck 28.03.13
Próbowałem '-r 2 -i blah.yuv -r 1', ale pokazuje mi błąd Opcja framerate not found.
Mark
Ach przepraszam ... Zadrapanie, to nie działa (już?) I tylko dla zdjęć.
slhck 28.03.13
1
@AnmolSinghJaggi Nie, to po prostu upuszcza klatki, ale nie byłbym pewien, że jest tak deterministyczne (tj. Upuszcza każdą nieparzystą klatkę). Będzie opierać się na kodach czasowych, które mogą nie być dokładne.
slhck
2

Jeśli twoja ffmpeg została zbudowana z flagą AviSynth, to wierzę, że możesz przekazać .avsplik.

Możesz to sprawdzić, uruchamiając ffmpegi szukając --enable-avisynthw danych konfiguracyjnych . --enable-avisynth

Jeśli to nie można go używać tak: ffmpeg -i blahEven.avs blahEven.yuv.

Gdzie blahEven.avsjest po prostu:

ffvideosource („blah.yuv”). SelectEven ()

W przypadku nieparzystych klatek użyj SelectOdd().

Aby uzyskać bardziej zaawansowane użycie, zobacz dokumentację SelectEvery .

Louis
źródło
To doskonała alternatywa, ale jak już wspomniałem - jestem ograniczony do używania tylko ffmpeg. Powodem tego jest to, że jest częścią zautomatyzowanego systemu, który utworzy tylko pliki .bat, bez możliwości dodania AVS.
Mark
@ Mark Myślałem, że jeśli --enable-avisynthtam jest, oznacza to, że AviSynth jest wbudowany w ffmpeg, ale nie jestem tego pewien.
Louis