javascript - 使用 Media Source Extension API 发出开始播放高可变比特率视频的问题

标签 javascript safari video-streaming media-source bitrate

问:视频播放卡死是什么原因?

我正在使用 Safari。

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

10596496 位/秒

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

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

"video/mp4; codecs=\"avc1.4d0028, mp4a.40.2\""

我的问题是,当在文件的某些区域寻找或启动流时,会导致 html5 视频播放器无限期停止。

我使用的服务器将文件作为实时流而不是范围字节请求提供。

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

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

我试过清空视频播放器,然后在搜索时每次发出新请求之前和之后重新加载它:

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)

我可以在网络选项卡中看到,在每次搜索时,向后端发出的提取请求确实接收到数据(最多 100 MB - 我将其限制在 100 MB 以内停止,以便源缓冲区不会运行内存不足)。正如您从日志中看到的那样,html5 视频播放器确实识别出正在接收数据,但在某些情况下,它认为它没有足够的数据来开始播放。

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

videoPlayer.buffered.end(0)
145.22842222222224

是什么导致视频播放无限期卡住?

最佳答案

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

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

所以我们有:

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

这实际上足以解决我的问题并允许开始播放视频。

关于javascript - 使用 Media Source Extension API 发出开始播放高可变比特率视频的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57209995/

相关文章:

ios - 在 iOS 10.3 发行版中无法下载内部使用的 iOS 应用程序

javascript - Safari 和 WKWebview 中的不同滚动行为

javascript - 如何解决我的 TypeScript/ESLint/Webpack 转译问题

javascript - D3.js 在线性刻度上使用序数刻度

javascript - npm install 没有更新依赖项

jQuery 中的 Javascript .files[0] 属性

css - 网站在 Safari 5.1.7 顶部有间距

几秒钟后Android webview停止播放

android - 从 iOS 到 Android 的点对点视频?

iOS 和直播 mjpeg