Вопрос или проблема
У меня есть команда, которая обрезает разные части одного и того же видео и объединяет их вместе, как видео, так и аудиодорожки, в файл 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: Пояснение команды
-
Извлечение субтитров:
[0:v]subtitles=episode.mkv:si=1
– извлекаем второй трек субтитров. Вы можете изменитьsi=1
на нужный индекс того трека, который хотите использовать.
-
Стилизация субтитров:
force_style='Fontsize=24,Fontname=SegoeUI.ttf,ScaleX=0.8'
– переопределение стиля субтитров.
-
Обработка фрагментов:
- Для каждого фрагмента используется
trim
для видео иatrim
для аудио, чтобы задать начало и конец извлечения с учетом временных меток.
- Для каждого фрагмента используется
-
Склеивание:
- Используется команда
concat
для соединения видео (v=1:a=0
) и аудио (v=0:a=1
) дорожек.
- Используется команда
-
Кодирование:
- Устанавливаются кодеки для видео
libx264
и аудиоlibopus
с заданными битрейтом.
- Устанавливаются кодеки для видео
Заключение
Данная команда позволит успешно соединить видеотреки и аудиотреки, а также вписать субтитры в итоговое видео. Обязательно протестируйте результат, чтобы убедиться, что все временные коды правильно соответствуют вашим фрагментам и что субтитры монтируются именно так, как вы хотите.
Если у вас возникнут дополнительные вопросы или потребуется углубленная настройка, не стесняйтесь обращаться за дополнительной информацией. Функциональность FFmpeg достаточно широка и позволяет настраивать каждую команду под конкретные потребности.