Как добавить резервный набор адаптации в манифест mpeg-dash, используя ffmpeg и Dash.js?

Ранее я успешно создавал манифесты mpeg-dash с помощью следующей команды ffmpeg:

      ffmpeg -i input.webm -c:v copy -c:a copy -f dash -seg_duration 15 manifest.mpd

Гдеinput.webmэтоVP9иopusзакодированный видеофайл, поэтому перекодирование не требуется. Поэтому я просто копирую оба потока.

Сейчас я пытаюсь добавить в этот манифест набор адаптации для тех устройств, которые не поддерживают VP9 и/или opus, с помощью следующей команды (переносы строк добавлены для разборчивости):

      ffmpeg -i input.webm 
-map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 
-c:v:0 copy 
-c:a:0 copy 
-c:v:1 libx264 -b:v:1 1000k 
-c:a:1 aac -b:a:1 128k
-adaptation_sets "id=0,streams=v id=1,streams=a" -f dash -seg_duration 15 manifest.mpd

Кажется, ffmpeg согласен со мной и выдает то, что я ожидал, а именно те же файлы, что и в предыдущей команде, и дополнительные файлы, напоминающие что-то вроде фрагментов mp4 и aac. Но мой сайт с Dash.js не принимает этот манифест, видео больше не воспроизводится. Также Dash.js не выдает никаких ошибок в консоли браузера. Что я сделал не так?

манифест:

      <?xml version="1.0" encoding="utf-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
    profiles="urn:mpeg:dash:profile:isoff-live:2011"
    type="static"
    mediaPresentationDuration="PT46.7S"
    maxSegmentDuration="PT15.0S"
    minBufferTime="PT40.0S">
    <ProgramInformation>
    </ProgramInformation>
    <ServiceDescription id="0">
    </ServiceDescription>
    <Period id="0" start="PT0.0S">
        <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="25/1" maxWidth="1920" maxHeight="1080" par="16:9">
            <Representation id="0" mimeType="video/webm" codecs="vp09.00.40.08" bandwidth="713" width="1920" height="1080" scanType="unknown" sar="1:1">
                <SegmentTemplate timescale="1000" initialization="init-stream$RepresentationID$.webm" media="chunk-stream$RepresentationID$-$Number%05d$.webm" startNumber="1">
                    <SegmentTimeline>
                        <S t="92" d="19200" r="1" />
                        <S d="8320" />
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
            <Representation id="2" mimeType="video/mp4" codecs="avc1.640028" bandwidth="1000000" width="1920" height="1080" sar="1:1">
                <SegmentTemplate timescale="12800" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                    <SegmentTimeline>
                        <S t="1024" d="244736" />
                        <S d="256000" />
                        <S d="97280" />
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
        <AdaptationSet id="1" contentType="audio" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true">
            <Representation id="1" mimeType="audio/webm" codecs="opus" bandwidth="96" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />
                <SegmentTemplate timescale="1000" initialization="init-stream$RepresentationID$.webm" media="chunk-stream$RepresentationID$-$Number%05d$.webm" startNumber="1">
                    <SegmentTimeline>
                        <S t="80" d="15001" />
                        <S d="15000" r="1" />
                        <S d="1757" />
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
            <Representation id="3" mimeType="audio/mp4" codecs="mp4a.40.2" bandwidth="128000" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />
                <SegmentTemplate timescale="48000" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                    <SegmentTimeline>
                        <S t="3152" d="720920" />
                        <S d="720896" r="1" />
                        <S d="81920" />
                    </SegmentTimeline>
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>

1 ответ

АнAdaptationSetдолжен содержать потоки с вариантами битрейта (Representations) только для одного кодека . В опубликованном вами примере MPD набор адаптации видео содержит варианты как для ваших видеопотоков VP9, ​​так и для H.264.

(Это связано с тем, что при использованииid=0,streams=vсинтаксис в FFMPEG, он поместит все ваши видеопотоки в один адаптационный набор.)

Я не проверял это, но изменение последней строки вашей команды ffmpeg на что-то вроде этого должно получить каждый кодек в своем собственном наборе адаптации:

      -adaptation_sets "id=0,streams=0 id=1,streams=1 id=2,streams=2 id=3,streams=3" -f dash -seg_duration 15 manifest.mpd
Другие вопросы по тегам