Javascript 问题:使用媒体源扩展API开始播放高可变比特率视频

Javascript 问题:使用媒体源扩展API开始播放高可变比特率视频,javascript,safari,video-streaming,media-source,bitrate,Javascript,Safari,Video Streaming,Media Source,Bitrate,问题:是什么导致视频播放无限期停滞 我在用Safari 我有一个具有相当高比特率的视频文件: 10596496位/秒 我怀疑在视频的整个持续时间(4分7秒)内,比特率变化很大 正在使用的mime类型编解码器字符串为: "video/mp4; codecs=\"avc1.4d0028, mp4a.40.2\"" 我的问题是,当在文件中的某些区域查找或启动流时,会导致html5视频播放器无限期暂停 我正在使用的服务器将该文件作为一个实时流,而不是远程字节请求 注意:这意味着当在文件中查找到某个时间

问题:是什么导致视频播放无限期停滞

我在用Safari

我有一个具有相当高比特率的视频文件:

10596496位/秒

我怀疑在视频的整个持续时间(4分7秒)内,比特率变化很大

正在使用的mime类型编解码器字符串为:

"video/mp4; codecs=\"avc1.4d0028, mp4a.40.2\""
我的问题是,当在文件中的某些区域查找或启动流时,会导致html5视频播放器无限期暂停

我正在使用的服务器将该文件作为一个实时流,而不是远程字节请求

注意:这意味着当在文件中查找到某个时间时,将启动一个新的实时流(我将旧的媒体源扩展对象与其源缓冲区一起拆下),我将创建一个新的媒体源对象,然后使用相同的mime类型编解码器字符串添加一个新的源缓冲区。基本上,查找就像启动一个新的播放会话

我已尝试确保在将最后一个视频文件块附加到源缓冲区后关闭媒体源

我已尝试清空视频播放器,然后在每次新请求之前和之后重新加载,以查找:

videoPlayer = document.getElementsByTagName('video')[0];
videoPlayer.src = '';
videoPlayer.load();
videoPlayer.src = URL.createObjectURL(myMediaSource);
videoPlayer.load();
我在本地html5视频播放器上添加了事件监听器,用于记录所有事件

如果我任意搜索到文件中已成功播放的点,我会看到以下控制台日志:

[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] LOADEDDATA (bundle.js, line 7131)
[Log] CANPLAY (bundle.js, line 7131)
[Log] PLAYING (bundle.js, line 7131)
[Log] CANPLAYTHROUGH (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)
[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)
如果我任意查找文件中的某个点,但该点未成功启动播放,我会看到以下控制台日志:

[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] LOADEDDATA (bundle.js, line 7131)
[Log] CANPLAY (bundle.js, line 7131)
[Log] PLAYING (bundle.js, line 7131)
[Log] CANPLAYTHROUGH (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)
[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)
我可以在网络选项卡中看到,在每次查找时,向后端发出的获取请求确实会接收数据(高达100 MB—我将其限制为停止在100 MB,以便源缓冲区不会耗尽内存)。正如您从日志中看到的,html5视频播放器确实能够识别接收到的数据,但在某些情况下,它认为它没有足够的数据开始播放

此外,我可以看到视频播放器在发出进度事件后正在缓冲视频的很大一部分,但它仍然被卡住:

videoPlayer.buffered.end(0)
145.22842222222224

是什么导致视频播放无限期停滞?

我相信我已经找到了原因和可行的解决方法

正如我在播放器无限期挂起而不开始播放的情况中提到的,videoPlayer.buffered.end(0)调用将返回一些合理的值,例如145.2284222224。然而,在这些情况下,缓冲启动时间似乎始终设置为0.08342222

因此,我们:

videoPlayer.buffered.start(0) // returns 0.08342222222222222
videoPlayer.buffered.end(0)   // returns 145.22842222222224
videoPlayer.currentTime // returns 0
这会欺骗safari视频播放器,使其认为没有足够的数据开始播放,因为视频播放器的当前时间不在缓冲开始时间和缓冲结束时间的范围内。我只需将视频播放器的当前时间设置为该范围内的某个值即可解决此问题,例如:

videoPlayer.currentTime = 0.9;
videoPlayer.play();
这实际上足以解决我的问题,并允许视频播放开始