TimeRanges для sourceBuffer не обновляется в Chrome - PullRequest
0 голосов
/ 27 января 2019

Я пытаюсь добавлять видеофрагмент в sourceBuffer каждые 5 секунд, это отлично работает в Firefox, но не в Chrome!

Я обнаружил, что после sourceBuffer updateend времядиапазон не обновляется в chrome!, его длина по-прежнему равна 0.

, но в Firefox его длина изменяется на 1.

Я не могу понять, что вызывает такое поведение.

это мой код:

var videoNumber = 1;
var video = document.querySelector('video');
var assetURL = '/classes/'+class_id+'/video/';
var segmentDuration = 5;
var duration = 5;
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/webm;  codecs="vp9, vorbis"';
var sourceBuffer;

var mediaSource;

if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
    mediaSource = new MediaSource;


    video.src = URL.createObjectURL(mediaSource);
    mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
    console.error('Unsupported MIME type or codec: ', mimeCodec);
}

/**
 * @desc start when video opened
 * @param _
 */
function sourceOpen (_) {
    console.log("source opened");
    //console.log(this.readyState); // open
    sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
    appendSegmentIfExist();
    video.addEventListener('timeupdate', checkBuffer);
    sourceBuffer.addEventListener('updateend', playVideo);

}

var tries = 0;
function fetchVideo(videoNumber,callback = function (response) {

}) {
    console.log("fetch video number "+ videoNumber);
    var xhr = new XMLHttpRequest;
    xhr.open('get', assetURL+videoNumber);
    xhr.responseType = 'arraybuffer';
    xhr.onloadend = function() {
        if(xhr.status === 404)
        {
            console.log('tries is '+ tries);
            if(tries > 3)
            {
                mediaSource.endOfStream();
                return;
            }
            tries++;
            fetchVideo(videoNumber,callback);
        }
        else
        {
            tries++;
            callback(xhr.response);
        }
    };
    xhr.send();
}

function appendSegment() {
    fetchVideo(videoNumber,function(buf)
    {
         if(videoNumber === 1)
             video.play().catch(function(e) {
                 console.log(e);
             });


        console.log(buf);
        sourceBuffer.timestampOffset = duration - 5;
        duration += 5;
        sourceBuffer.appendBuffer(buf);
        console.log(sourceBuffer);
    });
}

function shouldFetchNextSegment () {
    return video.currentTime > (segmentDuration*videoNumber - 1);
}

function checkBuffer () {
    if (shouldFetchNextSegment()) {
        console.log("should fetch next");
        console.log('time to fetch next chunk', video.currentTime);
        videoNumber++;
        appendSegment();
    }
}

function appendSegmentIfExist()
{
    console.log("check if there is video on server ");
    var xhr = new XMLHttpRequest;
    xhr.open('get', assetURL+videoNumber);
    xhr.responseType = 'arraybuffer';
    xhr.onloadend = function() {
        if(xhr.status === 404)
        {
            console.log('no video on server ');
        }
        else
        {
            appendSegment();
        }
    };
    xhr.send();
}

function playVideo() {
    console.log('update end');
    console.log(sourceBuffer.buffered);
    console.log(mediaSource.readyState);
    mediaSource.duration = Infinity;
    console.log(mediaSource.duration);
}

Я пробовал sourceBuffer.addEventListener('error', logError); и он возвращает объект ошибки, опять же, он только на Chrome.

...