I'm trying to create a Media Player with the use of Media Source Extension API. The Media Player works perfectly but I'm not able to understand a particular event. The sourceopen
addEventListner of the MediaSource
is declared at line 20. The sourceopen
adds the Source Buffer to the MediaSource and then appends to the Source Buffer. At line 21 and 13, I have included console loggings. When the Website is executed, the console outputs the console log of line 13 first. When from my point of view the console log of line 21 should be shown first. I believe that I'm not able to understand how the sourceopen
Event Listener works. Can someone Please explain why sourceopen
Event Listener is being exceuted after line 13. Thanks
If someone is not able to understand my question, please comment below.
01| <!DOCTYPE html>
02| <html>
03| <head>
04| <meta charset="utf-8"/>
05| </head>
06| <body>
07| <video controls></video>
08| <script>
09| var video = document.querySelector('video');
10| var assetURL = 'frag_bunny.mp4';
11| var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
12| start();
13| console.log('2');
14|
15| function start()
16| {
17| var mediaSource = new MediaSource;
18| video.src = URL.createObjectURL(mediaSource);
19|
20| mediaSource.addEventListener('sourceopen', function () {
21| console.log('1');
22| var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
23| fetchAB(assetURL, function (buf)
24| {
25| sourceBuffer.appendBuffer(buf);
26| });
27| });
28| }
29|
30| function fetchAB (url, cb)
31| {
32| var xhr = new XMLHttpRequest;
33| xhr.open('get', url);
34| xhr.responseType = 'arraybuffer';
35| xhr.onload = function ()
36| {
37| cb(xhr.response);
38| };
39| xhr.send();
40| };
41| </script>
42| </body>
43| </html>
A correct start()
function would be like this:
function start() {
// create an object, an instance of the MediaSource
var mediaSource = new MediaSource;
// to this `mediaSource` object add an event listener for the `sourceopen` event
// and run the code inside the function when `sourceopen` happens
mediaSource.addEventListener('sourceopen', function () {
console.log('1');
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.appendBuffer(buf);
});
});
// hey, `video` element, here is the source of the media I'd like you to play
// it's not a simple url, is something more complex
// , a `MediaSource` kind of thing
// and it might take you some time to be ready
video.src = URL.createObjectURL(mediaSource);
}
Now, back to the entire code..., if you tell the browser to execute a line like this:
console.log('2');
, the browser has no problem to do it immediately, you will see 2
in the console in no time.
But, this thing:
video.src = URL.createObjectURL(mediaSource);
is not that simple for the browser.
When you ask the browser to execute this, the browser is kind of saying: "Okay, you're asking me to execute, I will start now, and you can continue with the rest of the code, but, this one it's not that easy for me..., I need to start spinning some wheels..., it's going to take me some time..., also, I don't want to go out and fetch the video before I'm ready for it. I will let you know when I'm ready.
In fact, not directly me, the browser, but the mediaSource
object, which is an instance of MediaSource
which is one of my (the browser's) APIs, will let you know by raising a sourceopen
event.
So..., when you put this code on the page:
mediaSource.addEventListener('sourceopen', function () {
// do things
});
you're telling the browser what things to do when is ready and sourceopen
has fired.
Let's conclude:
12| start();
// start() is called and starts to execute but it has something inside that
// will take some time before ready
// as consequence `console.log('1')` does not happen yet
13| console.log('2');
// runs imediatelly
// you see "2" in the console
... some time passes, code inside start()
is getting things ready
// the `sourceopen` event fires and a `function ()`
// the callback of `mediaSource.addEventListener('sourceopen'`
// starts to execute
21| console.log('1');
// gets executed
// you see "1" in the console