FFMPEG: Небольшая разница во времени приводит к разнице в два кадра в выходных данных обрезки.

Вопрос или проблема

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

Например, мне нужно 44 кадра из ссылочного видео (FPS=30), начиная с заданного кадра.

Вот две попытки (с ffmpeg версии 6.1.1):

Попытка 1:

ffmpeg -i input.mp4 -vf "trim=start=3.2666666666666666:end=4.7333,setpts=PTS-STARTPTS" -an output.mp4

Попытка 2:

ffmpeg -i input.mp4 -vf "trim=start=3.2666666666666666:end=4.7334,setpts=PTS-STARTPTS" -an output.mp4

Хотя разница во времени end составляет всего 0.0001, первая попытка дает 43 кадра (продолжительность 1.433333 секунды), а вторая – 45 кадров (продолжительность 1.50 секунды). Независимо от того, что я ставлю в метку времени end, я не могу получить 44 кадра…

Я получаю количество кадров с помощью:

ffprobe -show_frames output.mp4 | grep FRAME | wc -l

(деля это число на два, так как оно считает как [FRAME], так и [/FRAME])

Каково объяснение этого поведения и как я могу предсказуемо обрезать необходимые мне кадры?

ОБНОВЛЕНИЕ То же самое поведение наблюдается, если я использую start_frame и end_frame. Для диапазона от 98 до 141 я получаю 43 кадра. Для диапазона от 98 до 142 я получаю 45 кадров. Я не могу получить 44…

Ответ или решение

Ответ на вопрос о проблемах с использованием FFMPEG для точного обрезания видео

Введение

Работа с видеофайлами требует высокой степени точности, особенно при использовании инструментов, таких как FFMPEG. В данном случае, вы столкнулись с проблемой, где небольшое изменение в метках времени приводит к различиям в количестве кадров при обрезке. Рассмотрим причины данной проблемы и возможные решения для точного обрезания видео.

Объяснение проблемы

Кадры и временные метрики

При работе с видео, срок между кадрами может быть разным в зависимости от используемого кодека и формата. Ваша задача заключается в обрезке видео так, чтобы получить точное количество кадров, например, 44 кадра, из видео с частотой 30 кадров в секунду. Это означает, что вам потребуется выделить 1,46667 секунды материала (44 кадра / 30 кадров в секунду).

Когда вы используете trim с параметрами start и end в формате времени, FFMPEG часто округляет временные метрики до ближайшего ключевого кадра. Это может привести к тому, что вы получите больше или меньше кадров, чем ожидали.

Различия в попытках обрезки

  1. В первой попытке: Используя диапазон от 3,26667 до 4,7333, вы получили 43 кадра. Это может быть связано с тем, что конечная временная метрика приводила к тому, что FFMPEG останавливается на ближайшем ключевом кадре, который находится за пределами желаемого диапазона.

  2. Во второй попытке: Увеличив конечное время всего на 0,0001 секунды, вы получаете 45 кадров. Это указывает на то, что добавленное время привело к захвату еще одного кадра из-за поведения кодера и того, как он обрабатывает временные метрики.

Как достичь желаемых результатов

Рекомендации для точного обрезания

  1. Постоянная частота кадров: Убедитесь, что ваше видео имеет постоянную частоту кадров (CFR). Это обеспечит лучшую предсказуемость при обрезке.

  2. Использование ключевых кадров (keyframes): Определите, где расположены ключевые кадры в вашем видео с помощью ffprobe. Это поможет вам точно понять, в каких временных метках можно производить обрезку.

    Пример команды:

    ffprobe -select_streams v -show_entries frame=pkt_pts_time,pkt_duration_time,key_frame -of csv input.mp4
  3. Пробные обрезания: Поскольку вы хотите получить точное количество кадров, вы можете применять метод проб и ошибок, начиная с диапазона, который уже дал вам результат. Например, если ваши предыдущие попытки дали 43 и 45 кадров, попробуйте установить end в 4.73325 или start в 3.26675.

  4. Используете флаги: Флаги, такие как -ss для начала обрезки и -t для указания времени, могут помочь в точном получении необходимого диапазона. Однако помните, что их применение также может привести к выбору ближайшего ключевого кадра.

Примеры корректных команд

Чтобы избежать проблем с кадрами, попробуйте следующее:

ffmpeg -i input.mp4 -ss 3.267 -t 1.46667 -c copy output.mp4

Или, если вам нужно больше контроля:

ffmpeg -i input.mp4 -vf "trim=start=3.2667:end=4.7333,setpts=PTS-STARTPTS" -an output.mp4

Не забывайте также проверять информацию о кадрах после обрезки, используя ffprobe, чтобы быть уверенным в результате.

Заключение

Точное обрезание видео в FFMPEG может быть достаточно сложной задачей. Следуя вышеописанным рекомендациям, можно значительно уменьшить вероятность возникновения ошибок и случайных изменений в количестве кадров. С учетом использования ключевых кадров и точных временных метрик, достижение требуемого результата станет более предсказуемым процессом.

Оцените материал
Добавить комментарий

Капча загружается...