Подтвердить что ты не робот

Извлеките каждый звук и субтитры из видео с помощью ffmpeg

У меня есть несколько звуковых дорожек и субтитров для извлечения в одном файле .mkv. Я новичок в командах ffmpeg, это то, что я пробовал (аудио):

ffmpeg -i VIDEO.mkv -vn -acodec copy AUDIO.aac

Он просто извлекает 1 аудио. Я хочу, чтобы ffmpeg извлечь все аудиофайлы и файлы субтитров в пункт назначения и сохранить исходное имя для каждого файла и расширений. (Потому что я не знаю, какое расширение делает аудиофайлы, иногда возможно .flac или .aac).

Я не уверен в решениях, которые я нашел в Интернете, потому что он довольно сложный, и мне нужны объяснения, чтобы знать, как он работает, чтобы я мог манипулировать командой в будущем. Кстати, я планировал запустить код из Windows CMD.

Спасибо.

4b9b3361

Ответ 1

В ffmpeg еще нет опции, чтобы автоматически извлекать все потоки в соответствующий контейнер, но это, безусловно, возможно сделать вручную. По умолчанию выбор потока выбирает только один поток для типа потока, поэтому вам нужно вручную сопоставить каждый поток.

1. Получить входную информацию

Используя ffmpeg или ffprobe, вы можете получить информацию в каждом отдельном потоке, и есть широкий диапазон форматов (xml, json, cvs и т.д.), доступных в соответствии с вашими потребностями.

ffmpeg пример

ffmpeg -i input.mkv

Получаемый результат (я вырезал некоторые дополнительные материалы, номера потоков и информацию о формате - это то, что важно):

Input #0, matroska,webm, from 'input.mkv':
  Metadata:
  Duration: 00:00:05.00, start: 0.000000, bitrate: 106 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
    Stream #0:1: Audio: vorbis, 44100 Hz, mono, fltp (default)
    Stream #0:2: Audio: vorbis, 44100 Hz, mono, fltp (default)
    Stream #0:3: Audio: vorbis, 44100 Hz, mono, fltp (default)
    Stream #0:4: Subtitle: ass (default)

ffprobe пример

ffprobe -v error -show_entries stream=index,codec_name,codec_type input.mkv

Результат:

[STREAM]
index=0
codec_name=h264
codec_type=video
[/STREAM]
[STREAM]
index=1
codec_name=vorbis
codec_type=audio
[/STREAM]
[STREAM]
index=2
codec_name=vorbis
codec_type=audio
[/STREAM]
[STREAM]
index=3
codec_name=vorbis
codec_type=audio
[/STREAM]
[STREAM]
index=4
codec_name=ass
codec_type=subtitle
[/STREAM]

2. Извлеките потоки

Используя информацию из одной из приведенных выше команд:

ffmpeg -i input.mkv \
-map 0:v -c copy video.mkv \
-map 0:a:0 -c copy audio0.oga \
-map 0:a:1 -c copy audio1.oga \
-map 0:a:2 -c copy audio2.oga \
-map 0:s -c copy subtitles.ass

В этом случае приведенный выше пример совпадает с:

ffmpeg -i input.mkv \
-map 0:0 -c copy video.mkv \
-map 0:1 -c copy audio0.oga \
-map 0:2 -c copy audio1.oga \
-map 0:3 -c copy audio2.oga \
-map 0:4 -c copy subtitles.ass

Ответ 2

Сначала вы должны указать все аудиопотоки:

ffmpeg -i VIDEO.mkv

а затем на основе вывода вы можете скомпилировать команду для извлечения аудиодорожек индивидуально.

Используя некоторую оболочку script, вы можете потенциально автоматизировать ее в файле script, чтобы вы могли сделать это в общем случае для любого файла mkv.

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

ffmpeg -threads 4 -i VIDEO.mkv -vn -an -codec:s:0.2 srt myLangSubtitle.srt

0.2 - это идентификатор, который вы должны прочитать из информации.

Ответ 3

Следующий скрипт извлекает все аудиопотоки из файлов в текущем каталоге

ls |parallel "ffmpeg -i {} 2>&1 |\
 sed -n 's/.*Stream \#\(.\+\)\:\(.\+\)\: Audio\: \([a-zA-Z0-9]\+\).*$/-map \1:\2 -c copy \"{.}.\1\2.\3\"/p' |\
 xargs -n5 ffmpeg -i {} "

Ответ 4

Я решил это так:

ffprobe -show_entries stream=index,codec_type:stream_tags=language -of compact $video1 2>&1 | { while read line; do if $(echo "$line" | grep -q -i "stream #"); then echo "$line"; fi; done; while read -d $'\x0D' line; do if $(echo "$line" | grep -q "time="); then echo "$line" | awk '{ printf "%s\r", $8 }'; fi; done; }

Выход:

result-ffprobre-list-streams

Установите только $ video1 var перед командой.

Наслаждайся этим!.