14

Есть ли точный способ взять необработанное видео и извлечь из него новое видео, которое содержит только нечетные или четные кадры (по выбору)?

Например:

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

Есть идеи, как это сделать, используя только FFmpeg?

2 ответа2

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 …
2

Если ваш ffmpeg был собран с флагом AviSynth, то я считаю, что вы можете передать файл .avs .

Вы можете проверить, запустив ffmpeg и --enable-avisynth в данных конфигурации . --enable-AviSynth

Если он есть, вы можете использовать его так: ffmpeg -i blahEven.avs blahEven.yuv .

Где blahEven.avs просто:

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .