Как объединить перекрывающиеся видеофрагменты в ffmpeg: пошаговое руководство

Представьте: вы пытаетесь вырезать из видео два фрагмента – скажем, с 4 по 6.5 секунду и с 5 по 6 секунду. Логично ожидать, что на выходе получится клип длиной 2.5 секунды (4-6.5) плюс 1 секунда (5-6). Но вместо этого ffmpeg упорно выдаёт только первый отрезок. В чём подвох? Дело в том, что фильтр select объединяет совпадающие интервалы, а не создаёт отдельные клипы. Но не спешите переустанавливать софт – решение проще, чем кажется.

Почему select не подходит для пересекающихся интервалов

Фильтр select (и его аудиоаналог aselect) работает как единое выражение. Если указать два перекрывающихся условия between(t,4,6.5)+between(t,5,6), он просто расширит зону выборки до 4–6.5 секунд. Это всё равно что наложить два прозрачных слоя: итоговая область будет равна их объединению, а не сумме.

Чтобы разделить отрезки, нужно:

  • Вырезать каждый фрагмент отдельно через trim
  • Сбросить временные метки через setpts (это как перезапустить таймер для каждого клипа)
  • Склеить результаты через concat

Правильный подход: filter_complex и цепочка фильтров

Вот рабочий пример команды, где сначала вырезаются два перекрывающихся отрезка, а потом они объединяются:

ffmpeg -y -i "input.mp4" ^  
-filter_complex "  
[0:v]trim=start=4:end=6.5,setpts=PTS-STARTPTS[v1];  
[0:a]atrim=start=4:end=6.5,asetpts=PTS-STARTPTS[a1];  
[0:v]trim=start=5:end=6,setpts=PTS-STARTPTS[v2];  
[0:a]atrim=start=5:end=6,asetpts=PTS-STARTPTS[a2];  
[v1][a1][v2][a2]concat=n=2:v=1:a=1[finalv][finala]  
" ^  
-map "[finalv]" -map "[finala]" "output.mp4"

Разберём ключевые моменты:

  1. trim/atrim – вырезает видео и аудио в указанных временных диапазонах. Обратите внимание: для аудио используется atrim, а не aselect.
  2. setpts/asetpts – сбрасывает временные метки фрагментов. Без этого concat будет считать, что второй клип начинается с 6.5 секунды, а не с нуля (из-за этого может возникнуть чёрный экран или рассинхрон).
  3. concat – склеивает фрагменты. Параметр n=2 указывает количество входных потоков, v=1:a=1 -число видео и аудиодорожек на каждый вход.

Совет: если аудио «уплывает» после склейки, проверьте, не забыли ли вы asetpts. Иногда помогает явное указание частоты дискретизации через -ar 44100 в аудиофильтрах.

Типичные ошибки и как их избежать

  1. Неправильный порядок фильтров. Сначала должен идти trim, потом setpts – иначе временные метки не сбросятся.
  2. Пропуск аудиодорожки. Если обработать только видео, ffmpeg может «додумать» аудио из первого фрагмента, что вызовет рассинхронизацию.
  3. Наложение эффектов. Если нужно добавить фильтры (например, поворот или цветокоррекцию), вставляйте их после trim, но перед setpts.

Пример команды с обработкой видео:

[0:v]trim=start=4:end=6.5,rotate=90,setpts=PTS-STARTPTS[v1]

И ещё один нюанс: при работе с filter_complex временные метки исходного файла игнорируются. Если ваш видеофайл начинается не с нуля (например, после предыдущих обрезок), используйте enable='between(t,start,end)' внутри trim.

Кстати, если фрагментов много, можно автоматизировать генерацию команды через скрипт – например, на Python или даже в Excel, подставляя start/end для каждого trim. Главное – не запутаться в нумерации потоков ([v1][a1][v2][a2] и т.д.).

Теперь вы знаете, как обходить ограничения select и собирать сложные клипы из пересекающихся отрезков. Осталось попрактиковаться – и ваши видео монтажные проекты станут гибкими как никогда.

Новое
Интересное