Вопрос или проблема
У меня есть видеопотоки, содержащие два аудиопотока (стерео и окружение) вот так:
Input #0, mpegts, from 'my-stream.ts':
Duration: 00:59:58.72, start: 26.658667, bitrate: 8013 kb/s
Program 1
Metadata:
service_provider: FFmpeg
Stream #0:0[0x100](deu): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 129 kb/s
Stream #0:1[0x101](deu): Audio: eac3 (EAC3 / 0x33434145), 48000 Hz, 5.1(side), fltp, 256 kb/s
Stream #0:2[0x102]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn
Теперь я пытаюсь преобразовать потоки в HLS, чтобы их можно было воспроизвести на Android с ExoPlayer, и пользователь мог выбирать между аудиопотоками (то есть, если пользователь нажимает кнопку настройки в правом нижнем углу, будут предложены оба аудиопотока для выбора).
Я пытался преобразовать это с помощью такой команды:
ffmpeg -i my-stream.ts -map 0:v:0 -map 0:a:0 -map 0:a:1 -codec:v copy -codec:a copy -f hls -hls_time 5 -hls_list_size 0 -hls_segment_filename "segment_%03d.ts" -master_pl_name "master.m3u8" -var_stream_map "v:0,a:0 v:0,a:1" -hls_flags independent_segments stream_%v.m3u8
но это приводит к ошибке
Same elementary stream found more than once in two different variant definitions #0 and #1
Должен признаться, я абсолютно не понимаю, что все это значит, поэтому не знаю, куда двигаться дальше.
Как правильно создать плейлист?
Как говорится в ошибке, вы используете один и тот же видеопоток в 2 вариантах, что не нравится ffmpeg:
-var_stream_map "v:0,a:0 v:0,a:1"
Необходимо, чтобы это были 2 разных потока:
-var_stream_map "v:0,a:0 v:1,a:1"
И затем маппинг должен это отражать:
-map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:1
Первая пара для потока 0
(с видеопотоком 0
и аудиопотоком 0
), вторая для потока 1
(с видеопотоком 0
и аудиопотоком 1
).
Ответ или решение
Для решения задачи конвертации видео потоков, содержащих две аудиодорожки (стерео и объемное) в формате HLS, чтобы их можно было воспроизвести на Android с помощью ExoPlayer и предоставить пользователю выбор между аудиопотоками, необходимы определенные действия с использованием ffmpeg и ExoPlayer. В первую очередь, это касается корректного определения вариативных потоков с различными аудиодорожками с использованием ffmpeg. Вы столкнулись с ошибкой, связанной с неправильной конфигурацией var_stream_map
, и вашей целью является создание корректного плейлиста.
Теория
При работе с ffmpeg и HLS необходимо учитывать, что HLS плейлист может содержать несколько вариантов потоков, между которыми пользователь может переключаться во время воспроизведения. В процессе подготовки HLS контента происходит разбиение медиафайлов на сегменты и создание индексного файла (master.m3u8
), в котором будут указаны доступные варианты медиа (разрешение, битрейт и т.д.).
В вашем случае задача заключается в создании вариативных потоков, позволяющих переключаться между стерео- и объемным звуковыми дорожками, сохраняя при этом одно и то же видеосодержимое.
Пример
У вас была попытка создать HLS-плейлист с использованием следующей команды:
ffmpeg -i my-stream.ts -map 0:v:0 -map 0:a:0 -map 0:a:1 -codec:v copy -codec:a copy -f hls -hls_time 5 -hls_list_size 0 -hls_segment_filename "segment_%03d.ts" -master_pl_name "master.m3u8" -var_stream_map "v:0,a:0 v:0,a:1" -hls_flags independent_segments stream_%v.m3u8
Команда не сработала из-за дублирования видеопотока в разных вариациях, что привело к появлению ошибки: Same elementary stream found more than once in two different variant definitions #0 and #1
.
Применение
Чтобы решить эту проблему и создать корректный плейлист, необходимо:
-
Разделить видеопотоки в
var_stream_map
. Несмотря на то, что сам видеофайл остается неизменным, нужно обозначить его разным образом для каждой аудиодорожки. Это поможет ffmpeg правильно интерпретировать вашу задачу. -
Пересмотреть использование
-map
. Убедитесь, что каждая комбинация видео и аудио корректно отображена вvar_stream_map
, чтобы гарантировать создание двух отдельных HLS-потоков, даже если видео остаётся тем же.
Вот исправленная команда:
ffmpeg -i my-stream.ts -map 0:v -map 0:a:0 -map 0:v -map 0:a:1 -codec:v copy -codec:a copy -f hls -hls_time 5 -hls_list_size 0 -hls_segment_filename "segment_%03d.ts" -master_pl_name "master.m3u8" -var_stream_map "v:0,a:0 v:0,a:1" -hls_flags independent_segments stream_%v.m3u8
-
Обратите внимание на изменения в
-map
: Мы явно указали, что одна и та же дорожка видео используется с каждой из аудиодорожек. -
Сегментация видео и аудио: Это позволит ExoPlayer обеспечивать переключение между аудиопотоками во время воспроизведения на мобильном устройстве.
На выходе вы получите плейлист в формате HLS, в котором каждая из аудиодорожек будет представлена отдельным вариантом. ExoPlayer сможет обрабатывать данный плейлист, и пользователь будет видеть оба варианта аудио в интерфейсе плеера.
Заключение
Правильное построение HLS-плейлиста с двумя аудиодорожками требует тщательной настройки параметров ffmpeg. Убедитесь, что каждый поток правильно отображен и не дублирован в var_stream_map
. В результате вы получите контент, поддерживающий переключение аудиодорожек в приложениях, использующих ExoPlayer, что обеспечит пользователю возможность выбора наилучшего звукового опыта.