- +1
MPEG-DASH视频传输中的常见问题
作者:Daniel Silhavy、Stefan Pham
翻译:Alex
技术审校:张博
作为 dash.js 项目的首席开发人员,我们经常面对这样的情况:我们必须评估 DASH 传输失败是由 dash.js 播放器实现中的实际 bug 引起,还是由错误的内容生成引起。在本文中,我们将分享一些在 DASH 传输中出现的常见错误,以及我们通常在面对这些错误时所总结的一些见解。
/ DRM 的特定问题 /
“想要安全,请使用 https”
在播放受到 DRM 保护的视频的时候,经常会出现一个与底层应用托管有关的错误。为了能够使用 EME(加密媒体扩展,DRM 播放以及与 CDM 通信时必须用到的 W3C API),Web 浏览器通常必须使用 https。如果使用 http 调用应用,dash.js 将输出警告:无法进行 DRM 播放。
No supported version of EME detected on this user agent! - Attempts to play encrypted content will fail!
保护自己免受保护
DRM 本身是一个比较复杂的话题。有一个显而易见的事实是:有三种主要的 DRM 系统,分别是:Google Widevine、Microsoft PlayReady 和 Apple FairPlay。在 Google Chrome 和 Mozilla Firefox 中,需要 Widevine 才能启动 DRM 播放,但是老款 Edge 却只支持 PlayReady。一些设备(如智能电视或者 FireTV)同时支持 Widevine 和 PlayReady。因此,在特定平台试图播放 DRM 保护内容之前,我们需要评估具体平台底层对 DRM 的功能支持。当使用 dash.js 时,一旦找到并选择了合适的 DRM 系统,就会显示如下输出:
DRM: KeySystem Access Granted (com.widevine.alpha)!
如果某个平台支持多种 DRM 系统,那么定义选择优先级会很有用。
{ "com.widevine.alpha": { "serverURL": "someurl", "priority": 1 }, "com.microsoft.playready": { "serverURL": "someurl", "priority": 2 } }
比如按照上例中的配置,dash.js 会优先考虑使用 Widewine DRM, 而不是 PlayReady。
你可以在之前的博文中了解到更多 DRM 知识:https://websites.fraunhofer.de/video-dev/enabling-hardware-drm-on-android-chrome-using-the-encrypted-media-extensions/
https://websites.fraunhofer.de/video-dev/dash-js-license-acquisition-for-multiple-eme-versions/
模式化一切
在《dash.js:多个 EME 版本的许可获取》(dash.js: License acquisition for multiple EME versions)[1] 一文中,我们描述了 dash.js 内容保护模型的概念,从中得到的关键点是:dash.js 实现了三种不同版本的 EME(被封装在不同的内容保护模型中)。遗憾的是,很多设备(向那些 “乐于” 为智能电视和机顶盒开发的人问候)需要定制其中一种保护模型。在此类设备上调试 DRM 问题时,这件事很值得做:总是检查 EME 调用是否需要被前置或者另做修改。
/ 播放时序的特定问题 /
“请保证您的播放器的当前播放时间不要掉出滑动窗口”
当开发 DASH 播放器或者创建 DASH MPD 时,一个关键概念是要理解 DASH 时序模型。你可以通过阅读
DASH-IF IOP guidelines[2] 和_DASH-IF implementation guidelines_: restricted timing model[3] 了解 DASH 时序模型。
我们经常遇到的一个问题由视频流引起,其中可用媒体切片的呈现时间在时移缓冲区之外。当给出了带有 <SegmentTimeline> 的明确时间信息时,播放器能够调整自身操作。下图就说明了这种调整:
播放器使用 MPD@timeShiftBufferDepth 属性确定 DVR 窗口。除此之外,从 “UTC now” 时间中减去当前的即时直播延迟时间,就能得到 “实际的 DVR 窗口时长”(比 “名义的 DVR 窗口时长” 要短)。在直播期间,上层应用只能在有效的 DVR 窗口内进行播放移动。
在上面的示例中,最后一个可用切片(第 5 个切片)的呈现结束时间在 DVR 窗口之外。在这种情况下,播放器将找不到可供下载和播放的切片。在这种情况下,dash.js 可以将 anchor time(基准时间)调整到最近已播放切片的 presentation end time(该切片的呈现截止时间),从而得出用于计算有效 DVR 窗口的调整值,以避免播放停顿。该功能通过调整设置参数实现,如下所示:
player.updateSettings({ streaming: { calcSegmentAvailabilityRangeFromTimeline: true } })
使用 Offset 避免 Upset
为了能够在 DASH 视频流中插入广告,MPD 经常使用多种分段时间。让我们来看一个非常简单的示例:我们想向主要内容(main content)添加一个中贴片广告。
这种情况下,我们在切换为广告内容前,先播放 8 秒主要内容。广告结束后,我们重新播放主要内容。所有分段持续时间总和构成了 18 秒媒体呈现持续时间。
为了将视频切片对应到媒体缓冲区中的目标位置,MSE 对切片的内部呈现时间戳(既最早的呈现时间 EPT,Earliest Presentation Time)添加了可配置的 timestampOffset。因此,应用可以通过调整 timestampOffset 控制切片在缓冲区中的位置。
现在,以上所述对我们的示例而言又有什么意义呢?让我们假设主要内容中的第一个切片和广告内容中的第一个切片的 EPT 为 0。在 DASH 视频流中,一个切片的呈现时间与其分段时间的开始有关。如果我们仅仅将每个切片的 MSE.timestampOffset 设置为每个分段时间的起始时间会发生什么?如下所示:分段时间 1 和分段时间 2 没有问题。
--- Period 1 --- MSE.timestampOffset = Period@start = 0 BufferPosition(Seg 1) = MSE.timestampOffset + EPT = 0 + 0 = 0 BufferPosition(Seg 4) = MSE.timestampOffset + EPT = 0 + 6 = 6 --- Period 2 --- MSE.timestampOffset = Period@start = 8 BufferPosition(Seg 1) = MSE.timestampOffset + EPT = 8 + 0 = 8 BufferPosition(Seg 2) = MSE.timestampOffset + EPT = 8 + 2 = 10
但问题出现在分段时间 3。因为我们从第 5 个切片开始,EPT 没有设置为 0。
--- Period 3 --- MSE.timestampOffset = Period@start = 12 BufferPosition(Seg 5) = MSE.timestampOffset + EPT = 12 + 8 = 20
没有将分段时间 3 的第一个切片定位在媒体呈现时间线中的第 12 秒,而是在第 20 秒时结束了。幸运的是,有一个方法很容易解决刚刚的问题:在 MPD 中,我们可以为每个时间段分配一个单独的 @presentationTimeOffset (注意:在此示例中,我们做了一些简化处理)。
在 MPD 中,对于每个 Representation 而言,@presentationTimeOffset 都不同。dash.js 使用 @presentationTimeOffset 来计算 MSE.timestampOffset。我们将 @presentationTimeOffset 的值设置为该时段中第一个切片的 EPT:
--- Period 3 --- MSE.timestampOffset = Period@start - @presentationTimeOffset = 12 - 8 = 4 BufferPosition(Seg 5) = MSE.timestampOffset + EPT = 4 + 8 = 12 BufferPosition(Seg 6) = MSE.timestampOffset + EPT = 4 + 10 = 14
现在所有切片都处在媒体缓冲区的正确位置,我们终于得到了一个连续的媒体呈现时间线。
关注缓冲 —— 前方空隙
基于 MSE 的播放器有一个大问题,那就是时间线中的时间空隙。大部分 MSE 实现无法处理这种情况,因为其中的媒体缓冲并不连续,而且一旦播放位置到达空隙,缓冲就会停止。那么当我们在讨论空隙以及产生空隙的原因时,到底意味着什么?从我们的经验来看,空隙主要由以下两个原因引起:
后续时间段没有对齐,结果时间段边界处的切片也无法对齐。
切片中的总媒体样本持续时间短于其呈现持续时间所指示的时间。
最终就导致了如下情况的发生:
在这种情况下,切片 1 和切片 2 完美对齐,然而切片 2 和切片 3 之间有一个空隙。为了避免出现播放停止,dash.js 会适时启用一个复杂的空隙跳转机制。可以通过如下设置启用和配置该机制:
player.updateSettings({ streaming: { jumpGaps: true, jumpLargeGaps: true, smallGapLimit: 1.5, } })
/ 结语 /
本篇文章中,我们分享了 MPEG-DASH 视频流中 6 种最常见的隐患。
当播放受到 DRM 保护的视频时,我们强调需要 https,并概括了使用特定 DRM 系统平台的重要性。除此之外,我们推动了实现 EME 旧版本的需求。
MPEG-DASH 的时序模型并不容易理解。错误的 DVR 窗口会导致播放停止和失败。在多时段广告插入的背景下,使用 MPD 的具体属性将时间段对齐以避免媒体缓冲的不连续很重要。此外,当 MSE 实现无法处理媒体缓冲中的空隙时,应避免媒体时间线中的空隙。
dash.js 播放器能够处理大部分以上情况,并帮助识别和解决此类问题。
如果你对我们的 DASH 活动或者 dash.js 有其他问题,可以随时查看我们的网站:https://www.fokus.fraunhofer.de/go/dash
注释:
[1]https://websites.fraunhofer.de/video-dev/dash-js-license-acquisition-for-multiple-eme-versions/
[2]https://dashif.org/guidelines/
[3]https://dashif-documents.azurewebsites.net/Guidelines-TimingModel/master/Guidelines-TimingModel.html
致谢:
本文已获得作者 Daniel Silhavy 授权翻译和发布,特此感谢。
原文链接:
https://websites.fraunhofer.de/video-dev/common-pitfalls-in-mpeg-dash-streaming/
本文为澎湃号作者或机构在澎湃新闻上传并发布,仅代表该作者或机构观点,不代表澎湃新闻的观点或立场,澎湃新闻仅提供信息发布平台。申请澎湃号请用电脑访问http://renzheng.thepaper.cn。
- 报料热线: 021-962866
- 报料邮箱: news@thepaper.cn
互联网新闻信息服务许可证:31120170006
增值电信业务经营许可证:沪B2-2017116
© 2014-2024 上海东方报业有限公司