Я пытаюсь создать Media Player с использованием Media Source Extension API. Media Player работает отлично, но я не могу понять конкретное событие. sourceopen
addEventListner из MediaSource
объявляется в строке 20. sourceopen
добавляет исходный буфер в MediaSource и затем добавляется к исходному буферу. На строках 21 и 13 я включил консольные сеансы. Когда веб-сайт выполняется, консоль выводит консольный журнал строки 13 в первую очередь. Когда с моей точки зрения, сначала должен быть показан консольный журнал строки 21. Я считаю, что я не могу понять, как работает sourceopen
Event Listener. Может кто-нибудь Пожалуйста, объясните, почему sourceopen
Event Listener исключается после строки 13. Спасибо
Если кто-то не в состоянии понять мой вопрос, пожалуйста, прокомментируйте ниже.
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>
Правильная функция start()
будет выглядеть так:
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 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);
}
Теперь вернемся ко всему коду..., если вы скажете браузеру выполнить такую строку:
console.log('2');
браузер не имеет проблем, чтобы сделать это немедленно, вы увидите 2
в консоли в кратчайшие сроки.
Но, эта вещь:
video.src= URL.createObjectURL(mediaSource);
не так просто для браузера.
Когда вы попросите браузер выполнить это, браузер вроде бы говорит: "Ладно, вы просите меня выполнить, я начну сейчас, и вы можете продолжить с остальной частью кода, но это не так, легко для меня..., мне нужно начать крутить колеса..., это займет у меня некоторое время..., также, я не хочу выходить и получать видео, пока я не готов к этому Я дам вам знать, когда я буду готов.
На самом деле, не напрямую я, браузер, но объект mediaSource
, который является экземпляром MediaSource
который является одним из моих (браузеров) API, позволит вам узнать, подняв событие sourceopen
.
Итак... когда вы помещаете этот код на страницу:
mediaSource.addEventListener('sourceopen', function () {
// do things
});
вы говорите браузеру, что делать, когда он готов, и sourceopen
уволен.
Позвольте заключить:
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
... некоторое время проходит, код внутри start()
готовится к работе
// 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
console.log('1');
,