Не удалось добавить сегменты с помощью Media Source API, получите «InvalidStateError: была предпринята попытка использовать объект, который не является или больше не может использоваться

Я использую следующий пример программы для добавления медиафайлов, но получаю сообщение «Uncaught InvalidStateError: была предпринята попытка использовать объект, который не является или больше не может использоваться» в первый момент, когда он попадает в код «mediaSource.sourceBuffers [0] .appendBuffer(mediaSegment);". Я использую Chrome 31.0.1650.57. Может ли кто-нибудь посоветовать мне решить эту проблему?

https://github.com/jbochi/media-source-playground/blob/master/test.html

Я сделал следующую модификацию для добавления файлов.

var buffer_len = 0;

function HaveMoreMediaSegments(){
    //return false; //return buffers.length > 0;
    return buffers.length > buffer_len;
}

// var GetNextMediaSegment = GetInitializationSegment;

function GetNextMediaSegment(){
    var buffer = buffers[buffer_len];
    buffers = buffers.slice(1);
    buffer_len = buffer_len + 1;
    return buffer;
}

И изменился

mediaSource.sourceBuffers[0].append(mediaSegment);

to

mediaSource.sourceBuffers[0].appendBuffer(mediaSegment);

И

sourceBuffer.append(initSegment);

to

sourceBuffer.appendBuffer(initSegment);

Поскольку метод добавления не работает в моей среде.

И я использую sourceopen вместо webkitsourceopen внутри события window.setTimeout().

mediaSource.addEventListener('sourceopen', onSourceOpen.bind(this, video));

person User5791    schedule 18.11.2013    source источник


Ответы (2)


Проблема в том, что после добавления данных экземпляр SourceBuffer становится временно непригодным для использования, пока он работает. В это время свойство updating объекта SourceBuffer будет установлено на true, поэтому его легко проверить.

Но, вероятно, самый простой способ справиться с этим - прослушать событие updateend, просто поставить в очередь все свои буферы и добавить их только тогда, когда SourceBuffer сообщит вам, что он готов для нового. Как это:

// store the buffers until you're ready for them
var queue = [];

// whatever normally would have called appendBuffer(buffer) can 
// now just call queue.push(buffer) instead

sourceBuffer.addEventListener('updateend', function() {
  if ( queue.length ) {
    sourceBuffer.appendBuffer(queue.shift());
  }
}, false);

Имейте в виду, что для того, чтобы сработало первое событие, вам нужно добавить первый буфер вручную, а не проталкивать его в queue. После этого просто сбрасываем все в массив.

person Kevin Ennis    schedule 21.01.2014
comment
если срабатывает updateend и в очереди ничего нет, а затем вы что-то добавляете в очередь, то это никогда не будет добавлено в исходный буфер. - person Sean; 23.11.2016
comment
Конечно. Таким образом, 1_ - person Kevin Ennis; 28.11.2016

Вы нашли ответ? Здесь та же проблема :(

У меня есть временное решение, которое устанавливает setTimeout для каждого добавления буфера, так как вам нужно дождаться завершения обновления предыдущего буфера (sourceBuffer.updating == false). Код может выглядеть так:

var i = 0;
stream.on('data', function (buffer) {
    setTimeout(function(){
        sourceBuffer.appendBuffer(buffer);
    }, (i++) * 200);
});
person BnoL    schedule 03.12.2013