Почему прослушиватель событий Sourceopen выполняется в конце сценария?

1

Я пытаюсь создать 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>
Теги:
addeventlistener
media-source

1 ответ

0

Правильная функция 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
  • 0
    Спасибо, что приложили много усилий, чтобы ответить на мой вопрос. Теперь я понял, почему цифра 2 отображается в консоли раньше 1. Но есть ли альтернативный способ предотвратить это? Как в коде не должен обрабатываться, пока sourceopen не сделал свою работу. Или как я могу использовать ту же структуру моего кода и все же каким-то образом заставить sourceopen выполнить свою работу сначала, а затем перейти к следующей строке кода, как это возможно ?. Причина, по которой мне нужно, чтобы это произошло, заключается в том, что я проектирую сложный видеоплеер, который будет работать только с sourceopen, выполняющим свою работу в первую очередь. Спасибо
  • 0
    Вы можете поместить все, что вы хотите, чтобы после того, как sourceopen был запущен, в другую функцию, а затем вызвать эту функцию из того места, где у вас теперь console.log('1'); ,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню