Знищити всі парні або непарні кадри за допомогою FFmpeg?


14

Чи є точний спосіб зняти сире відео та витягнути з нього нове відео, яке містить лише непарні кадри чи парні кадри (за вибором)?

Наприклад:

У мене є "бла.юв" з 400 кадрів (0-399). Я хочу створити "blahOdd.yuv", який містить кадри 1-399 (1,3,5,7 ... 399) та "blahEven", що містить кадри 0-398 (0,2,4,6 ... 398 ).

Будь-які ідеї, як це зробити, використовуючи лише FFmpeg?

Відповіді:


11

Щоб точно працювати, спочатку перетворіть відео в бітовий потік RAW YUV (якщо його ще немає):

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

Наступний крок: selectФільтр приймає вираз , де nзнаходиться номер кадру.

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

Щоб ffmpegне дублювати кадри, ви повинні примусити половину частоти кадрів вашого вводу - так ви встановите "2" як вхід, а "1" на вихід. Не забудьте замінити WxH фактичними розмірами кліпу, оскільки в сирому бітовому потоці немає заголовка, який містить цю інформацію.

Замість сказаного, іншою можливістю було б додати setptsфільтр, щоб встановити нові часові позначки для виводу. Але будьте обережні, оскільки вона не точно опускає кадри. Ось 25 - це фактична вихідна частота кадрів, яку ви бажаєте:

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

Ви, звичайно, можете вибрати інший формат пікселів (будь-який з ffmpeg -pix_fmts). Переконайтесь, що, читаючи файл, ви знаєте розмір пікселя та формат пікселя:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …

Дякуємо, для нових версій FFMPEG має бути -vf замість -filter: v. Крім того, він повинен бути mod (n-1 \, 2), оскільки число n здається починається з 1, тоді як кількість кадрів починається з 0 (інакше перший кадр дублюється 3 рази). Але проблема все ще є, вона дублює кадри, хоча я хочу їх позбутися - наприклад, заключний кліп буде містити лише половину кадрів.
Марк

-vfпсевдонім -filter:v. Я зараз не можу надійно перевірити це, але розберуся це пізніше, коли я знову буду на своїй машині. Може, tinterlaceфільтр може зробити те саме?
slhck

Я спробував '-r 2 -i blah.yuv -r 1', але він показує мені помилку .
Марк

Ах вибачте. Подратуйте це, це не працює (більше?) І лише для зображень.
slhck

1
@AnmolSinghJaggi Ні, це просто опускає кадри, але я не був би впевнений, що це так детерміновано (тобто скидає кожен непарний кадр). Він базуватиметься на часових кодах, які можуть бути неточними.
slhck

2

Якщо ваш ffmpeg був побудований з прапором AviSynth, то я вважаю, що ви можете передати .avsфайл.

Ви можете перевірити, запустивши ffmpegі шукає --enable-avisynthв конфігурації даних. --доступний-avisynth

Якщо там ви можете використовувати його , наприклад , так: ffmpeg -i blahEven.avs blahEven.yuv.

Де blahEven.avsпросто:

ffvideosource ("bla.yuv"). SelectEven ()

Для непарних кадрів використовуйте SelectOdd().

Для більш розширеного використання див. Документацію SelectEvery .


Це відмінна альтернатива, але, як я вже згадував, я обмежуюсь використовувати лише ffmpeg. Причиною тому є те, що це частина автоматизованої системи, яка створюватиме лише .bat файли, немає можливості для додавання AVS.
Марк

@Mark Я думав, що якщо --enable-avisynthвін є, це означає, що AviSynth був вбудований у ffmpeg, але я не впевнений у цьому.
Луї
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.