Как объединить несколько фрагментов видео, одновременно жестко встраивая субтитры (ffmpeg)

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

У меня есть команда, которая обрезает разные части одного и того же видео и объединяет их вместе, как видео, так и аудиодорожки, в файл mp4:

ffmpeg `
    -ss 15:23.465 -to 15:35.561 -i episode.mkv `
    -ss 16:06.258 -to 16:21.565 -i episode.mkv `
    -ss 16:57.643 -to 19:31.213 -i episode.mkv `
    -filter_complex '[0:v][0:a:1][1:v][1:a:1][2:v][2:a:1]concat=n=3:v=1:a=1[outv][outa]' `
    -map '[outv]' `
    -map '[outa]' `
    -c:v libx264 -b:v 4500k `
    -c:a libopus -b:a 128k -ac 2 -f mp4 `
    out.mp4

Но я также хотел бы встроить одну из встроенных дорожек субтитров srt в финальное видео в той же команде. Я пытался изменить аргумент -filter_complex следующим образом:

 -filter_complex '[0:v]subtitles=episode.mkv:si=1[v0];[1:v]subtitles=episode.mkv:si=1[v1];[2:v]subtitles=episode.mkv:si=1[v2];[v0][0:a:1][v1][1:a:1][v2][2:a:1]concat=n=3:v=1:a=1[outv][outa]' `

Но субтитры не синхронизированы правильно. Первый отрезок начинается с ~15 минут, но субтитры показываются с 0 минут, второй отрезок начинается с 16, но субтитры тоже начинаются с 0 минут и т. д.

Как мне следует написать эту команду, чтобы получить желаемый результат?

Это сработало:

ffmpeg -i episode.mkv -filter_complex `
 "[0:v]subtitles=episode.mkv:si=1:force_style="Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8"[vs1]; `
  [0:v]subtitles=episode.mkv:si=1:force_style="Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8"[vs2]; `
  [0:v]subtitles=episode.mkv:si=1:force_style="Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8"[vs3]; `
  [vs1]trim=start="00\:15\:23.465":end='00\:15\:35.561',setpts=PTS-STARTPTS[v1]; `
  [0:a:1]atrim=start="00\:15\:23.465":end='00\:15\:35.561',asetpts=PTS-STARTPTS[a1]; `
  [vs2]trim=start="00\:16\:06.258":end='00\:16\:21.565',setpts=PTS-STARTPTS[v2]; `
  [0:a:1]atrim=start="00\:16\:06.258":end='00\:16\:21.565',asetpts=PTS-STARTPTS[a2]; `
  [vs3]trim=start="00\:16\:57.643":end='00\:19\:31.213',setpts=PTS-STARTPTS[v3]; `
  [0:a:1]atrim=start="00\:16\:57.643":end='00\:19\:31.213',asetpts=PTS-STARTPTS[a3]; `
  [v1][v2][v3]concat=n=3:v=1:a=0[outv]; `
  [a1][a2][a3]concat=n=3:v=0:a=1[outa]" `
  -map "[outv]" -map "[outa]" `
  -c:v libx264 -b:v 1M `
  -c:a libopus -b:a 128k -ac 2 -y `
  out2.mp4

Мне пришлось установить встраивание для каждого отрезка (vs1, vs2 и vs3).

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

Для того чтобы склеить несколько фрагментов видео и одновременно встроить субтитры из встроенной дорожки SRT в итоговый файл с помощью FFmpeg, необходимо воспользоваться специальными фильтрами в команде. Давайте рассмотрим процесс шаг за шагом, чтобы вы могли получить желаемый результат.

Шаг 1: Извлечение и подготовка фрагментов

Сначала мы будем извлекать нужные фрагменты видео и аудио. Обратите внимание, что для каждого отдельного фрагмента нужно будет задать временные метки:

ffmpeg -i episode.mkv -filter_complex "
    [0:v]subtitles=episode.mkv:si=1:force_style='Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8'[vs1];
    [0:v]subtitles=episode.mkv:si=1:force_style='Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8'[vs2];
    [0:v]subtitles=episode.mkv:si=1:force_style='Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8'[vs3];
    [vs1]trim=start=15:23.465:end=15:35.561,setpts=PTS-STARTPTS[v1];
    [0:a]atrim=start=15:23.465:end=15:35.561,asetpts=PTS-STARTPTS[a1];
    [vs2]trim=start=16:06.258:end=16:21.565,setpts=PTS-STARTPTS[v2];
    [0:a]atrim=start=16:06.258:end=16:21.565,asetpts=PTS-STARTPTS[a2];
    [vs3]trim=start=16:57.643:end=19:31.213,setpts=PTS-STARTPTS[v3];
    [0:a]atrim=start=16:57.643:end=19:31.213,asetpts=PTS-STARTPTS[a3];
    [v1][v2][v3]concat=n=3:v=1:a=0[outv];
    [a1][a2][a3]concat=n=3:v=0:a=1[outa]" \
-map "[outv]" -map "[outa]" \
-c:v libx264 -b:v 1M \
-c:a libopus -b:a 128k -ac 2 -y \
out.mp4

Шаг 2: Пояснение команды

  1. Извлечение субтитров:

    • [0:v]subtitles=episode.mkv:si=1 – извлекаем второй трек субтитров. Вы можете изменить si=1 на нужный индекс того трека, который хотите использовать.
  2. Стилизация субтитров:

    • force_style='Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8' – переопределение стиля субтитров.
  3. Обработка фрагментов:

    • Для каждого фрагмента используется trim для видео и atrim для аудио, чтобы задать начало и конец извлечения с учетом временных меток.
  4. Склеивание:

    • Используется команда concat для соединения видео (v=1:a=0) и аудио (v=0:a=1) дорожек.
  5. Кодирование:

    • Устанавливаются кодеки для видео libx264 и аудио libopus с заданными битрейтом.

Заключение

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

Если у вас возникнут дополнительные вопросы или потребуется углубленная настройка, не стесняйтесь обращаться за дополнительной информацией. Функциональность FFmpeg достаточно широка и позволяет настраивать каждую команду под конкретные потребности.

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

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