FFmpeg: удалить неподдерживаемые потоки субтитров (MKV)

380
Wolveix

Я делаю скрипт, который просматривает список медиа-файлов, а затем перекодирует их с помощью FFmpeg. Моя проблема заключается в том, что мне нужно удалить все субтитры, которые не поддерживает контейнер MKV. Это должно быть просто с использованием отрицательного отображения, однако номер потока будет отличаться для каждого файла. Вот моя текущая команда:

ffmpeg -y -i "path/to/file.ext" -map 0 -c:v libx264 -crf 20 -level 4.1 -profile:v high -c:a copy -q:a 100 -preset faster -strict -2 -movflags faststart -threads 2 -nostdin -stats "file.mkv" 
1

1 ответ на вопрос

2
Wolveix

Я не верю, что FFmpeg изначально поддерживает это. Мне удалось выписать сценарий, который позволяет для одного или нескольких случаев:

stream_count=$(/usr/bin/ffprobe -select_streams s -show_entries stream=index,codec_name -of csv=p=0 "path/to/file.ext" |& grep -cE 'Subtitle: dvd_subtitle|Subtitle: hdmv_pgs' || :) if [ "$stream_count" -gt 0 ] then stream_id=$(/usr/bin/ffprobe -select_streams s -show_entries stream=index,codec_name -of csv=p=0 "path/to/file.ext" |& grep -E 'Subtitle: dvd_subtitle|Subtitle: hdmv_pgs' || :) if [ "$stream_count" = 1 ] then exclude_stream=$(echo "$stream_id" | grep -oP '0:[0-9]') exclude_stream="-map -$exclude_stream" else counter=0 until [ "$counter" = "$stream_count" ] do counter=$((counter+1)) excluded_stream="$(echo "$stream_id" |& grep -oP '0:[0-9]' |& sed -n "$"p)" if [ ! -z "$excluded_stream" ] then if [ "$exclude_stream" = "*$excluded_stream*" ] #If ffprobe returns encode errors within the streams, double results may be returned for the problematic stream which this circumvents then counter="$stream_count" else exclude_stream="$exclude_stream -map -$excluded_stream" fi fi excluded_stream="" done fi fi ffmpeg -y -i "path/to/file.ext" -map 0 $exclude -c:v libx264 -crf 20 -level 4.1 -profile:v high -c:a copy -q:a 100 -preset faster -strict -2 -movflags faststart -threads 2 -nostdin -stats "file.mkv" #exclude isn't wrapped as it invalidates the opening hyphen 

Если у кого-нибудь есть какие-либо предложения по улучшению этого сценария, я бы хотел их услышать.

Спасибо @LordNeckbeard за предложенные изменения в команде ffprobe.

Я считаю, что анализировать машиночитаемые выходные данные проще и последовательнее, чем читаемые человеком: `ffprobe -loglevel error -select_streams s -show_entries stream = index, codec_name -of csv = p = 0 input.ext` LordNeckbeard 5 лет назад 2
@LordNeckbeard Спасибо за предложение. Мне пришлось убрать флаг loglevel из-за возможности ошибок кодирования на найденных потоках Wolveix 5 лет назад 0
Вы можете опустить `-profile: v` и` -level` и позволить кодировщику выбирать, если вам не нужно иметь дело с устройством с ограниченным воспроизведением. `-threads` - это еще одна опция, с которой кодировщик автоматически справляется. `-strict -2` не требуется, если ваш ffmpeg старый и использует ранее экспериментальный встроенный кодировщик AAC. [FFmpeg WIki: AAC] (https://trac.ffmpeg.org/wiki/Encode/AAC) говорит, что «эффективный диапазон для` -q: a` составляет около 0,1-2. Этот VBR является экспериментальным и, вероятно, получится худшие результаты, чем у ЦБ РФ (`-b: a`)". Я никогда не изучал это, поэтому я не могу комментировать это утверждение. LordNeckbeard 5 лет назад 1
`-level`,` -profile: v` и `-threads` намеренно существуют из-за предполагаемого использования скрипта. Пропуск `-strict -2` вызывал проблемы в прошлом, но по общему признанию я не проверял это недавно. Интересно насчет `-q: a`, я добавил его по рекомендации. Спасибо за информацию! Wolveix 5 лет назад 0
Я удалил -strict -2 и никаких проблем не возникало. Спасибо за понимание. Wolveix 5 лет назад 0

Похожие вопросы