1.0.1 • Published 1 year ago

when-sourcebuffer-ready v1.0.1

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 year ago

when-sourcebuffer-ready

Execute callback when sourceBuffer.updating becomes false, or immediately if it's already false.

If this function was called several times while sourceBuffer.updating === true then callbacks are executed in the same order as this function was called.

Usage

console.log(sourceBuffer.updating); // false
execWhenSourceBufferReady(sourceBuffer, () => {
  sourceBuffer.appendBuffer(buffer1);
  console.log('appendBuffer() 1 executed');
});
// 'appendBuffer() 1 executed'

console.log(sourceBuffer.updating); // true
// `sourceBuffer.updating === true`, but we can still queue
// another `appendBuffer()`.
execWhenSourceBufferReady(sourceBuffer, () => {
  sourceBuffer.appendBuffer(buffer2);
  console.log('appendBuffer() 2 executed');
});
// A few moments later:
// 'appendBuffer() 2 executed'

Why

This

function naiveExecWhenSourceBufferReady(buffer) {
    if (!sourceBuffer.updating) {
      sourceBuffer.addEventListener("updateend", () => {
        sourceBuffer.appendBuffer(buffer);
      }, { once: true });
    } else {
      sourceBuffer.appendBuffer(buffer);
    }
}
naiveExecWhenSourceBufferReady(buffer1);
setTimeout(() => naiveExecWhenSourceBufferReady(buffer2), 50);
setTimeout(() => naiveExecWhenSourceBufferReady(buffer3), 100);

is not enogh. Because the "updateend" event callback is not executed synchronously as .updating becomes false. So it might so happen that, if you used the above naive approch, buffers would be appended in wrong order. The third buffer might check if (!sourceBuffer.updating) { and go on executing appendBuffer() before the "updateend" event callback is executed for the second buffer, which could result in an error.

How it works

Nothing fancy. It keeps a queue (array) of callbacks for each SourceBuffer.

Why I made the project

The cloning algorithm of the Jump Cutter browser extension and the webxdc-video-call app needed it.

TODO

Certain operations on MediaSource (not SourceBuffer), such as setting duration can cause an error

If the updating attribute equals true on any SourceBuffer in sourceBuffers

so perhaps we need to write a similar function that checks .updating on all SourceBuffers of a MediaSource.