Обрезка видео в точных кадрах с фильтром ffmpeg select

16

Вместо использования -ssи -toпоиска параметров, которые кажутся не очень точными, могу ли я вырезать видео для заданных номеров кадров? Например;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[80-й кадр и 560-й кадр включены. Таким образом, в сумме получается (560 - 80 +1) кадров]

После ответов и немного поиска, я попробовал несколько команд. Но пока я не мог найти приемлемый путь.

Если кто-то хочет сократить поток видео между 250-м и 750-м кадрами, это путь. Это даст 501 кадр в качестве вывода:

Примечание: movie.mp4 имеет 25 кадров в секунду и частоту дискретизации звука 48k

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Как и ожидалось, выходная длина составляет ровно 20 секунд.

Используя тот же метод для аудио:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Неожиданно этот имеет очень плохую точность. Он должен был дать мне 960001 (960k + 1) сэмплов, что равняется 20 секундам звука. Но вместо этого результат был 20,505 секунд и имеет 984240 сэмплов. Также, если я увеличу продолжительность, увеличится и ошибка.

Затем я попытался использовать параметры -ss -to для обрезки аудиопотока:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

Старый классический способ работает намного лучше. Выход был 20.003 секунд и 960144 сэмплов. Плюс, увеличение продолжительности не увеличивает ошибку, ошибка постоянна, всегда есть 144 выборки излишков с этим входным файлом.

Подводя итог: selectфильтр работает хорошо в большинстве случаев, но выбор нет. Классические -ssпараметры работают лучше для аудио, но не с точностью до сэмпла. Кроме того, невозможно использовать -vf selectи -ssпараметры вместе, потому что -ssэто повлияет как на аудио, так и на видео потоки, в то время как мы хотим, чтобы это влияло только на аудио.

Итак, чтобы точно вырезать медиа-файл, я должен сделать эти 3 шага:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

Это дает наиболее точные результаты. Продолжительность видео составляет 20 000 секунд, а качество кадра - 20,003 секунды, сэмпл 960144. Не совсем совпадает с видео потоком, но это нормально. Существует только 144 излишков образцов. Самым большим недостатком является то, что когда я хочу вырезать файл, мне нужно отправить 3 команды для простой работы, и он создает два ненужных файла: a_stream.webm и v_stream.webm. И selectфильтр не работает на некоторых входных файлах, которые я пробовал. Он выполняет работу успешно (?), Но никогда не останавливает процесс кодирования, поэтому мне приходится каждый раз закрывать командную строку.

destor
источник
Я прочитал эту страницу, прежде чем опубликовать этот вопрос. Эта страница не помогла мне. Если вход имеет переменную fps, мы можем просто рассчитать, используя это уравнение? Я так не думаю. Также я не думаю, что '-ss' даст мне точную позицию. Покадровый поиск будет лучше, я думаю.
Разрушитель
Обратите внимание, что -ssс точностью до кадра (см. Здесь ). У вас на самом деле есть переменная ввода в секунду? Мой ответ ссылается на ветку списка рассылки, в которой упоминаются selectфильтры, в которых вы можете указать номер кадра. Вы пробовали это?
Slhck
Я пытался использовать selectи aselectфильтры для видео и аудио потоков. Selectс точностью до кадра для видео, но aselectне с точностью до выборки. На самом деле это далеко не так. Это дает гораздо худшие результаты, чем использование простых параметров -ss -to. Из-за этого на данный момент я использую комбинацию selectфильтра и -ss -toпараметров, чтобы добиться наиболее точной резки. Но это безобразный способ сделать это. Пожалуйста, посмотрите на мой первый пост, я добавил некоторые
командные
версия ffmpeg?
тьфу
Почему вы пытаетесь сократить номер кадра в любом случае. Если нужна такая точность, то почему бы не использовать avidemux? Также, возможно, ваши первоначальные проблемы заключаются в том, что он выбирает ближайший ключевой кадр?
тьфу

Ответы:

3

Звук исходит из секунд, а не кадров, поэтому, если вы хотите вырезать видео, вам нужно рассчитать частоту кадров в секунду × 20 секунд следующим образом: 20 секунд из 23,97 кадров в секунду = 479,4

Вырезание кадра не является точным, потому что вы не можете получить полный кадр в секунду за последнюю секунду, поэтому аудио будет получать больше секунд или только полсекунды или чуть больше или меньше! Возможно, вы должны использовать секунды вместо фреймов, чтобы получить точную обрезку, вы говорите ffmpeg сделать это за вас. И если вы получите 1 дополнительный кадр, что насчет замены 250-го и 750-го кадров на 250-й и 749-й кадры ?! Используйте минус 1, чтобы всегда получать сколько кадров вы просите!

Мойтаба Голестани
источник
На самом деле звук исходит из сэмплов, а не секунд ...
Anubioz