Представьте: вы пытаетесь вырезать из видео два фрагмента – скажем, с 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"
Разберём ключевые моменты:
- trim/atrim – вырезает видео и аудио в указанных временных диапазонах. Обратите внимание: для аудио используется
atrim
, а неaselect
. - setpts/asetpts – сбрасывает временные метки фрагментов. Без этого concat будет считать, что второй клип начинается с 6.5 секунды, а не с нуля (из-за этого может возникнуть чёрный экран или рассинхрон).
- concat – склеивает фрагменты. Параметр
n=2
указывает количество входных потоков,v=1:a=1
-число видео и аудиодорожек на каждый вход.
Совет: если аудио «уплывает» после склейки, проверьте, не забыли ли вы
asetpts
. Иногда помогает явное указание частоты дискретизации через-ar 44100
в аудиофильтрах.
Типичные ошибки и как их избежать
- Неправильный порядок фильтров. Сначала должен идти
trim
, потомsetpts
– иначе временные метки не сбросятся. - Пропуск аудиодорожки. Если обработать только видео, ffmpeg может «додумать» аудио из первого фрагмента, что вызовет рассинхронизацию.
- Наложение эффектов. Если нужно добавить фильтры (например, поворот или цветокоррекцию), вставляйте их после
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
и собирать сложные клипы из пересекающихся отрезков. Осталось попрактиковаться – и ваши видео монтажные проекты станут гибкими как никогда.