FFMPEG / DASH-LL создает аудио и видео фрагменты с разной скоростью; игрок сбит с толку (ошибка 404)

Я пытаюсь создать прямой эфир MPEG-DASH из статического файла для тестирования различных режимов с низкой задержкой. Мультиплексор DASH в FFmpeg создает два набора AdaptationSet, один для фрагментов видео и один для фрагментов звука.

Однако файлы фрагментов аудио и видео создаются с разной скоростью (должно быть?). т.е. здесь stream0 - это фрагменты видео, а stream1 - фрагменты звука. После нескольких секунд работы корневой каталог будет содержать:

chunk-stream0-00001.m4s  chunk-stream1-00001.m4s  
chunk-stream0-00002.m4s  chunk-stream1-00002.m4s  
chunk-stream0-00003.m4s  chunk-stream1-00003.m4s  
chunk-stream0-00004.m4s  chunk-stream1-00004.m4s  
                         chunk-stream1-00005.m4s  
                         chunk-stream1-00006.m4s  
                         chunk-stream1-00007.m4s  
                         chunk-stream1-00008.m4s  
                         chunk-stream1-00009.m4s  
master.mpd  
init-stream0.m4s  
init-stream1.m4s  

Поток не загружается (и не воспроизводится) ни на dash.js, ни на shaka-player, и есть много 404 (Not Found) ошибок для фрагментов видео. Проигрыватель последовательно запрашивает фрагменты как из потока0, так и из потока1, т. Е. Поток0-001 + поток1-001, затем поток0-002 + поток1-002 и так далее.

Но поскольку stream0 переходит только с 001 на 004, возникает множество ошибок 404, когда он пытается загрузить потоки от stream0-005 до 009.

Разрыв увеличивается после того, как FFmpeg некоторое время работает. например, stream0 - от 62 до 75, а stream1 - от 174 до 187. Перезагрузка страницы проигрывателя в этот момент завершается неудачно с dash.all.debug.js:15615 [2055][FragmentController] No video bytes to push or stream is inactive. и показывает 404 ошибки stream0 chunk 188 (который еще не существует!)

введите описание изображения здесь

Команда FFmpeg была заимствована из потоковой передачи DASH сверху вниз:

ffmpeg -re -i /mnt/swdevel/TestStreams/H264/ThreeHourMovie.mp4 \
-c:v libx264 -x264-params keyint=120:scenecut=0 -b:v 1M -c:a copy \
-f dash -dash_segment_type mp4 \
 -seg_duration 2 \
 -target_latency 3 \
 -frag_type duration \
 -frag_duration 0.2 \
 -window_size 10 \
 -extra_window_size 3 \
 -streaming 1 \
 -ldash 1 \
 -use_template 1 \
 -use_timeline 0 \
 -write_prft 1 \
 -fflags +nobuffer+flush_packets \
 -format_options "movflags=+cmaf" \
 -utc_timing_url "/pelican/testPlayers/time.php" \
 master.mpd

А код проигрывателя dash.js очень прост:

const srcUrl = "../ottWebRoot/playerTest/master.mpd"; 

var player = dashjs.MediaPlayer().create();

let autoPlay = false;
player.initialize(document.querySelector("#videoTagId"), srcUrl, autoPlay);

player.updateSettings(
{
    streaming :
    {
        lowLatencyEnabled : true,
        liveDelay : 2,
        jumpGaps : true,
        jumpLargeGaps : true,
        smallGapLimit : 1.5,
    }
});

Чтобы предоставить элемент UTCTiming в манифесте, небольшой URL-адрес time.php возвращает время в формате UTC с веб-сервера:

<?php
    print gmdate("Y-m-d\TH:i:s\Z");
?>

(Он также показывает 404 ошибки для последнего фрагмента stream1 / audio, вероятно, это другая проблема)

Я не уверен, что попробовать дальше. Любые предложения и предложения очень ценятся.

ИЗМЕНИТЬ I

Предложение @Anonymous Coward изменить интервал между ключами значительно улучшило ситуацию. Фрагменты для stream0 и stream1 находятся в режиме блокировки и имеют одинаковые порядковые номера.

Однако по-прежнему существует много ошибок 404 как при начальной загрузке страницы (без нажатия кнопки воспроизведения), так и во время воспроизведения.

Я запустил watch -n 1 ls -lt <webRootFolder и параллельно сравнил с ошибками в консоли браузера. Трудно сравнивать, но это выглядит так, как будто браузер пытается получить файлы на краю воспроизведения, которые еще не были созданы FFmpeg. См. Картинку ниже.

Как мне указать браузеру подождать еще немного, прежде чем загружать граничные фрагменты?

введите описание изображения здесь

ИЗМЕНИТЬ II

Использование shaka-player вместо dash.js воспроизводит правильно без ошибок 404. Настроен как:

    player.configure(
    {
        streaming: 
        {
            lowLatencyMode: true,
            inaccurateManifestTolerance: 0,
            rebufferingGoal: 0.1,
        }
        
    });

Клиент

  • MacOS 10.12
  • dash.js последняя версия 3.2.2
  • Chrome 79, Safari 12, FireFox v?

Сервер

  • Apache 2.4.37
  • PHP 7.2.4 (только для функции времени)
  • Centos 8

(Для справки, вот файл mpd, созданный FFmpeg)

<?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="dynamic"
    minimumUpdatePeriod="PT500S"
    availabilityStartTime="2021-05-24T14:50:00.263Z"
    publishTime="2021-05-24T15:22:45.335Z"
    timeShiftBufferDepth="PT50.0S"
    maxSegmentDuration="PT2.0S"
    minBufferTime="PT5.0S">
    <ProgramInformation>
    </ProgramInformation>
    <ServiceDescription id="0">
        <Latency target="3000" referenceId="0"/>
    </ServiceDescription>
    <Period id="0" start="PT0.0S">
        <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="24/1" maxWidth="1280" maxHeight="682" par="15:8" lang="und">
            <Resync dT="200000" type="0"/>
            <Representation id="0" mimeType="video/mp4" codecs="avc1.64081f" bandwidth="1000000" width="1280" height="682" sar="1023:1024">
                <ProducerReferenceTime id="0" inband="true" type="captured" wallClockTime="2021-05-24T14:50:00.263Z" presentationTime="0">
                    <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-xsdate:2014" value="/pelican/testPlayers/time.php"/>
                </ProducerReferenceTime>
                <Resync dT="5000000" type="1"/>
                <SegmentTemplate timescale="1000000" duration="2000000" availabilityTimeOffset="1.800" availabilityTimeComplete="false" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
        <AdaptationSet id="1" contentType="audio" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" lang="und">
            <Resync dT="200000" type="0"/>
            <Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" bandwidth="116317" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />
                <ProducerReferenceTime id="1" inband="true" type="captured" wallClockTime="2021-05-24T14:50:00.306Z" presentationTime="0">
                    <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-xsdate:2014" value="/pelican/testPlayers/time.php"/>
                </ProducerReferenceTime>
                <Resync dT="21333" type="1"/>
                <SegmentTemplate timescale="1000000" duration="2000000" availabilityTimeOffset="1.800" availabilityTimeComplete="false" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
                </SegmentTemplate>
            </Representation>
        </AdaptationSet>
    </Period>
    <UTCTiming schemeIdUri="urn:mpeg:dash:utc:http-xsdate:2014" value="/pelican/testPlayers/time.php"/>
</MPD>

person Danny    schedule 24.05.2021    source источник
comment
Если он работает в Shaka, но не в dash.js, было бы хорошо сообщить об ошибке команде dash.js, поскольку я знаю, что они много работали над LL-DASH: github.com/Dash-Industry-Forum/dash.js/issues/new/choose   -  person Anonymous Coward    schedule 27.05.2021


Ответы (1)


Вход ThreeHourMovie.mp4 имеет частоту кадров 24 Гц (см. AdaptationSet@frameRate), поэтому установка keyint на 120 будет давать IDR каждые пять секунд на выходе x264.

Вы инструктируете мультиплексор DASH (через seg_duration) выводить и сигнализировать 2-х сегменты, но это невозможно, поскольку сегмент должен начинаться с IDR (как указано в руководстве, которое вы связали). Таким образом, мультиплексор выводит сегменты 5s, но сигнализирует 2s в манифесте, что явно неверно.

Измените keyint на правильное кратное seg_duration (то есть keyint=48 в данном случае), и он, вероятно, начнет работать.

person Anonymous Coward    schedule 25.05.2021
comment
Спасибо! Это значительно улучшило его. Однако по-прежнему проблема с ошибкой 404 при извлечении файлов края. См. РЕДАКТИРОВАТЬ I в основном вопросе. Какие-либо предложения? - person Danny; 26.05.2021
comment
Я поменял liveDelay в плеере но все то же самое ... - person Danny; 26.05.2021