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 не работает с некоторыми входными файлами, которые я пробовал. Это делает работу успешно (?) но никогда не останавливает процесс кодирования, поэтому мне приходится каждый раз закрывать командную строку.

1 ответ1

2

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

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

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