Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not append segments by Media Source API, get "InvalidStateError : An attempt was made to use an object that is not, or is no longer, usable

I use following sample program to append media files, but get "Uncaught InvalidStateError : An attempt was made to use an object that is not, or is no longer, usable" error at the first instant it hits code "mediaSource.sourceBuffers[0].appendBuffer(mediaSegment);". I am using Chrome 31.0.1650.57. Can anyone advice me to resolve this?

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

I have done following modification to append files.

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;
}

And changed

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

to

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

And

sourceBuffer.append(initSegment);

to

sourceBuffer.appendBuffer(initSegment);

As append method is not working in my environment.

And I use sourceopen instead of webkitsourceopen inside window.setTimeout() event.

mediaSource.addEventListener('sourceopen', onSourceOpen.bind(this, video));
like image 764
User5791 Avatar asked Nov 18 '13 07:11

User5791


1 Answers

The problem is that after you append data, the SourceBuffer instance becomes temporarily unusable while it's working. During this time, the SourceBuffer's updating property will be set to true, so it's easy to check for.

But probably the simplest way to deal with this is to listen to the updateend event, and just queue up all your buffers and only append them when the SourceBuffer tells you it's ready for a new one. Like this:

// 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);

Keep in mind that in order for the first event to fire, you need to append the first buffer manually, rather than pushing to queue. After that, just dump everything into the array.

like image 53
Kevin Ennis Avatar answered Sep 29 '22 00:09

Kevin Ennis