Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么要在脚本末尾执行Sourceopen事件侦听器?_Javascript_Addeventlistener_Media Source - Fatal编程技术网

Javascript 为什么要在脚本末尾执行Sourceopen事件侦听器?

Javascript 为什么要在脚本末尾执行Sourceopen事件侦听器?,javascript,addeventlistener,media-source,Javascript,Addeventlistener,Media Source,我正在尝试使用媒体源扩展API创建媒体播放器。媒体播放器工作得很好,但我无法理解某个特定事件。第20行声明了MediaSource的sourceopenaddEventListner。sourceopen将源缓冲区添加到MediaSource,然后附加到源缓冲区。在第21行和第13行,我包含了控制台日志。当执行网站时,控制台首先输出第13行的控制台日志。在我看来,应该首先显示第21行的控制台日志。我相信我无法理解sourceopen事件侦听器是如何工作的。有人能解释一下为什么在第13行之后执行了

我正在尝试使用媒体源扩展API创建媒体播放器。媒体播放器工作得很好,但我无法理解某个特定事件。第20行声明了
MediaSource
sourceopen
addEventListner。
sourceopen
将源缓冲区添加到MediaSource,然后附加到源缓冲区。在第21行和第13行,我包含了控制台日志。当执行网站时,控制台首先输出第13行的控制台日志。在我看来,应该首先显示第21行的控制台日志。我相信我无法理解
sourceopen
事件侦听器是如何工作的。有人能解释一下为什么在第13行之后执行了
sourceopen
事件侦听器吗。谢谢

如果有人不能理解我的问题,请在下面评论

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>
01|
02| 
03|   
04|     
05|   
06|   
07|     
08|     
09 | var video=document.querySelector(“视频”);
10 | var资产='frag_bunny.mp4';
11 | var mimeCodec='视频/mp4;编解码器=“avc1.42E01E,mp4a.40.2”;
12 |开始();
13 |控制台日志('2');
14|
15 |功能启动()
16|       {
17 | var mediaSource=新的mediaSource;
18 | video.src=URL.createObjectURL(mediaSource);
19|       
20 | mediaSource.addEventListener('sourceopen',function(){
21 |控制台日志('1');
22 | var sourceBuffer=mediaSource.addSourceBuffer(mimeCodec);
23 | fetchAB(组件、功能(buf)
24|           {
25 | sourceBuffer.appendBuffer(buf);
26|           });
27|         });
28|       } 
29|
30 |函数fetchAB(url,cb)
31|       {
32 | var xhr=新的XMLHttpRequest;
33 | xhr.open('get',url);
34 | xhr.responseType='arraybuffer';
35 | xhr.onload=函数()
36|         {
37 | cb(xhr.响应);
38|         };
39 | xhr.send();
40|       };
41|     
42|   
43| 
正确的
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'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);

}
现在,回到整个代码…,如果您告诉浏览器执行如下一行:

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

}
console.log('2')

,浏览器立即执行此操作没有问题,您将立即在控制台中看到
2

但是,这件事:

video.src=URL.createObjectURL(mediaSource)

对于浏览器来说并不是那么简单

当您要求浏览器执行此操作时,浏览器会说:“好的,你要求我执行,我现在就开始,你可以继续剩下的代码,但是,这一个对我来说不是那么容易…,我需要开始旋转一些轮子…,这将需要我一些时间…,而且,我不想在我准备好之前出去拿视频。”。我准备好了会告诉你的

事实上,不是直接的浏览器我,而是
mediaSource
对象,它是我(浏览器)的API之一
mediaSource
的一个实例,它将通过引发
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()
中的代码正在准备就绪


21 | console.log('1')


谢谢你花了很多精力来回答我的问题。我现在已经理解了为什么2在1之前显示在控制台中。但有没有其他方法可以防止这种情况发生。在sourceopen完成它的工作之前,代码不应该进行处理。或者,我如何使用相同的代码结构,仍然以某种方式使sourceopen先完成它的工作,然后继续执行下一行代码,就像在“这是可能的吗?”?。我之所以需要这样做,是因为我正在设计一个复杂的视频播放器,它只能在sourceopen先完成它的工作的情况下工作。感谢您可以在sourceopen激发另一个函数后,将希望发生的一切放入另一个函数中,然后从现在的
console.log('1')调用该函数
// gets executed
// you see "1" in the console