Это немного сложно, но вот рабочий метод:
INFILE=input.ts
OUTFILE=output.mkv
ffmpeg \
-i "${INFILE}" \
-f lavfi -i movie="${INFILE}[out+subcc]" \
-map 0 -map 1:s \
-codec:v libx264 \
-codec:a copy \
-codec:s srt \
-metadata:s:s:0 language=eng \
"${OUTFILE}"
Здесь input.ts
и output.mkv
находятся желаемые входные MPEG-TS и выходные Matroska файлы соответственно. Обобщение к сценарию оставлено читателю в качестве упражнения.
Интерпретация параметров, строка за строкой:
-i ...
это входной файл.
-f lavfi -i ...
позволяет извлечь извлеченный поток титров.
-map 0 -map 1:s
выбирает потоки для вывода.
-codec:v libx264
говорит ffmpeg конвертировать видео в H.264.
-codec:a copy
копирует все аудиопотоки на выход без изменений.
-codec:s srt
говорит ffmpeg преобразовать встроенные подписи в SRT.
-metadata:s:s:0 language=eng
устанавливает язык потоков субтитров на английский.
Заметки:
- Я использовал это только с эфирными потоками ATSC, включая, как я полагаю, заголовки EIA-608. Я понятия не имею, работает ли он с записями QAM (кабель), хотя я ожидаю, что это работает.
- У вас могут возникнуть проблемы с именами входных файлов, содержащих определенные символы, даже если вы поместите имя файла в кавычки.
- Это скопирует все аудио потоки. Если вы хотите только первый, вам нужно явно отобразить отдельные потоки из ввода 0.
- Скорее всего, у аудиопотоков уже установлен язык. Если это не так, добавьте еще один параметр -metadata, чтобы установить язык аудиопотока.
- Скорее всего, вы захотите поэкспериментировать с качеством кодирования видео, используя опцию -crf. Если ваше входное видео чересстрочное, вы также можете деинтерлейсировать и масштабировать до 720p, добавляя
-filter:v bwdif=0,scale=1280:720
после -map
строки (ей).