8

Я пытаюсь использовать FFmpeg для разделения видео на основе некоторых входных данных start_time и end_time и замены их другими видеофайлами. Например, для ввода 10 15 мне нужно заменить EXACT секунд 10 to 15 другое видео.

ХОРОШО. Что приходит мне в голову это:

  1. Сначала разделите видео (в данном случае 0-10, 10-15 и 15-конец)
  2. Заменить 10-15 другим видео
  3. Объединить все суб-видео обратно

Первый вопрос: это лучшее и самое быстрое решение? Есть ли у нас более простая команда или другие инструменты для замены определенного периода времени в видео другим видео?

Второй вопрос: если предположить, что FFmpeg является жизнеспособным решением, когда я просто использую команду ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4 , мой код обработки видео не может прочитать и обработать файл. Я использовал инструмент mediainfo для сравнения двух файлов и заметил различия в размерах заголовков, хотя все, что связано с видеокодеком, было одинаковым. Я заметил, что размер заголовка отличается, что, очевидно, вызывает проблему. Есть ли способы заставить размер заголовка также (кроме кодеков) быть одинаковым?

ОБНОВЛЕНИЕ: Вот оригинальный файл .mp4 который отлично работает в эмуляторе.

1 ответ1

7

Использование trim и concat - исходных файлов с разными кодеками

Для этого убедитесь, что ваши отдельные файлы имеют одинаковое разрешение и в идеале одинаковую частоту кадров и частоту дискретизации и т.д. Это предотвратит ошибки или сбои во время объединения.

Вы можете сделать все за один раз, не разбивая файл, используя фильтры trim и concat :

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Здесь trim используется для указания отдельных частей входных видеопотоков (0:v , 1:v), которые вы позже хотите объединить. Эти части названы от v0 до v2 . (Фильтр setpts сбрасывает временные метки этих отдельных частей в 0, что необходимо для объединения). Позже мы объединяем три части.

Если вы хотите обрезать определенную временную метку до конца, используйте trim=start=15 вместо указания диапазона.

Если в ваших файлах есть аудио, вы должны обрезать эти потоки отдельно:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

Обратите внимание, что видео и аудио будут перекодированы в этом случае - убедитесь, что вы указали соответствующие целевые показатели качества вывода (например, -crf для x264, x265 или libvpx-vp9). Вы можете прочитать больше об этом в FFmpeg Wiki, например, для VP9 или H.264.

Использование отдельных сегментов

Если вы хотите разделить клипы и позже собрать их:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Если в файлах есть аудио, используйте тот же подход, что и выше:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Это снова перекодирует видео поток. Это немного более просто, но в остальном должно быть эквивалентно вышеуказанному методу.

Использование concat concat

В принципе, вы также можете попытаться объединить битовые потоки без перекодирования, используя демультиплексор concat. Создайте файл с именем concat.txt и добавьте следующие записи (соответствующие созданным выше видеоклипам):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Затем объедините эти отдельные файлы:

ffmpeg -f concat -i concat.txt -c copy output.avi

Однако это требует, чтобы ваши клипы имели одинаковый кодек, разрешение, частоту кадров и т.д., Поэтому он не работает со всеми видами разнородных источников.

Использование протокола concat

Описанный выше тип конкатенации на уровне файлов также может быть достигнут с использованием протокола concat с теми же ограничениями, что и выше (тот же кодек, разрешение и т.д.):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Для получения дополнительной информации о соединении, прочитайте соответствующую страницу FFmpeg Wiki.

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