支持在 Web 浏览器中使用加密媒体扩展和 Microsoft PlayReady DRM
万维网联合会 (W3C) HTML5 加密媒体扩展 (EME) 为网站引入了一项功能,可在不使用插件的情况下播放受数字版权管理 (DRM) 保护的内容。Windows 8.1 上的 Internet Explorer 11 支持结合使用 EME 和 Microsoft PlayReady DRM。 本指南介绍了其他浏览器如何在 Windows 8.1 上采用类似方式启用 Microsoft PlayReady DRM 播放。
该信息适用于以下操作系统:
- Windows 8.1
简介
浏览器中的 DRM
有一段时间浏览器可以播放受 DRM 保护的内容,最常见的方式是支持启用 DRM 的 Adobe Flash 或 Microsoft Silverlight 版本。 这些组件过去作为浏览器插件提供。 它们(及其基础媒体平台)过去用于标准化媒体管道并为最终用户免费提供插件播放。
插件可以限制与 Web 内容兼容的设备,这样可支持 HTML 扩展,这些扩展允许浏览器直接支持丰富的功能,并减少对插件组件的需求。 上一个示例中添加了渐进式播放 HTML5 中添加的媒体内容。 这样允许浏览器直接播放媒体文件,不需要使用任何媒体播放器插件。 现在,新的规范已定义 HTML 功能,这些功能允许自适应流式播放受 DRM 保护的媒体。
随着 Windows 8.1 的发布,IE11 支持高级 HTML 流式传送扩展。 使用这些新扩展,Internet Explorer 可以在受到大范围的网络和系统约束下播放多种来源的高级视频内容,无须使用浏览器插件。 Windows 8.1 设计使用 Microsoft PlayReady DRM,并适用于传统桌面和新体验桌面浏览器版本。
两个 W3C Web 规范支持在 Windows 8.1 上的 IE11 中使用以下新功能:
- 媒体源扩展:此规范定义支持自适应流式传送的 HTMLMediaElement 扩展。 它允许 JavaScript 为音频和视频元素动态构造流,方法是将分段附加到媒体 sourceBuffer。 JavaScript 可以实现自适应流式处理,方法是调整这些附加分段的质量级别以响应一系列的网络或媒体渲染瓶颈。
- 加密媒体扩展:此规范定义支持内容保护系统的 HTMLMediaElement 扩展。 它允许标识浏览器支持的保护技术,并且为密钥交换定义支持播放受 DRM 保护媒体的方法。
如果在 Web 浏览器中组合使用自适应流式处理和 DRM 播放功能,则允许使用高级媒体消耗体验,该体验得到 Web 服务器发布的 JavaScript 的完全支持,并且可能由适用于所有设备种类的可互操作浏览器解决方案进行托管。
IE11 支持 Microsoft PlayReady DRM 的媒体源扩展和加密媒体扩展。 本指南的作用是提供其他浏览器实现 Windows 8.1 上运行的浏览器中类似功能所需的信息。
Microsoft PlayReady DRM
Microsoft PlayReady 是一个数字版权管理 (DRM) 系统,它提供了对多种设备和计算机的支持。 它采用以下几种方式支持:
- Microsoft PlayReady 移植工具包:提供了可轻松部署的实现方法和源代码,允许在任一设备(不论操作系统如何)上都支持 Microsoft PlayReady 客户端。
- Microsoft PlayReady 许可证服务器:用于托管颁发受 DRM 保护内容播放许可证所需的许可证服务。
还有一个 Microsoft PlayReady PC 软件开发工具包 (SDK),用于为具有 DRM 功能的传统 Windows 应用程序提供 Windows 桌面运行时。 此 SDK 仍然处于活动状态,但不是 IE11 用于实现 Microsoft PlayReady 支持的方法。
新的应用模型首次在 Windows 8 中发布时,还发布了 Microsoft PlayReady AppX 框架。 它支持从 Windows 应用商店下载应用,并且与其他预安装的应用一起暂存,以便成为 Windows 8 和之后强大系统上首次运行体验的一部分。
Windows 8.1 中的 IE11 会利用暂存 Microsoft PlayReady 框架的优势。 它虽然不是 Windows 组件(它在单独的进程中开发和编译),但是可用于所有启用媒体的 Windows SKU,因此可供 Windows 8.1 上运行的新体验浏览器使用。
加密媒体扩展 CDM
加密媒体扩展 (EME) 规范定义了内容解密模型 (CDM),该模型将通用 EME API 转换为特定 DRM 解决方案可能需要的特定数据交换。 该操作允许一般化 EME,从而将系统特定方面留给 CDM 处理。
Windows 8.1 应用使用的 Microsoft PlayReady 框架包含 CDM 功能。 并且设备的 Microsoft PlayReady 移植工具包中还包含了 CDM 接口支持。 如果使用 Windows 8.1 系统框架和其他设备的启用 CDM 的移植工具包,则允许 Microsoft PlayReady 支持大量系统和设备上运行的浏览器。
此指南的目标是仅详细介绍此 CDM 支持的 Windows 8.1 方面。
实现方法
概述
过去,在 Microsoft PlayReady SDK 上为 Windows 构建的应用负责授权该技术、符合严格的媒体管道要求,以确保以解密的形式一次性保护媒体,并且这些应用还具备与其 Microsoft PlayReady 许可证关联的金融义务。 为 Windows 8 开发的 Microsoft PlayReady 框架(现在已针对 Windows 8.1 使用 EME/CDM 支持扩展)为选择使用它的应用提供了强劲优势:
- 已授予技术:如此这样,就不需要使用单独的许可证。 应用将构建在公开记录的 API 上并提供启用 Microsoft PlayReady 且无其他授权的系统。
- 已保护媒体管道的安全:Microsoft PlayReady 框架使用 Microsoft 媒体基础实现的媒体服务,并且此管道已构建并认证符合 DRM 要求。 应用免费使用此管道,不需要任何其他认证(或根据设计变化重新认证)。
IE11 中的 EME 实现方法使用特别为 EME 支持构建的更新媒体基础 API。 这是为 Windows 8.1(和以后版本)上运行的其他浏览器(桌面和新体验)推荐的实现方法。
技术 | 说明 |
使用 MF 实现浏览器 MSE/EME API | 新的媒体基础 API 直接映射到 W3C MSE 和 EME 标准中介绍的 API。 |
附加 IMFMediaSourceExtension 对象 | 将 MSE API 映射到其 MF 等效后,浏览器必须将 IMFMediaSourceExtension 对象附加到元素中。 |
PlayReady AppX 框架 | AppX 框架通常会基于应用清单中声明的依存关系进行注册。 对于新体验桌面浏览器,在用户第一次登录时会自动执行此操作。 |
支持 In Private | Internet Explorer 分离 Microsoft PlayReady 许可证存储用于 In Private 并在 In Private 会话结束时删除该存储。 这样会删除可能已在 In Private 会话过程中存储的许可证。 |
支持选项卡挂起 | 选项卡挂起将新体验浏览器上的选项卡分成单独的进程,并允许 Microsoft WindowsWindows 中的电源管理功能管理哪些选项卡在后台保持活动状态和挂起哪些选项卡可改进浏览器电源配置文件。 选项卡挂起具有特定的实现方法要求,浏览器必须符合这些要求才能保证媒体体验正常运行。 |
媒体基础 API
若要支持 Microsoft PlayReady EME,浏览器必须将 MSE 和 EME API 实现到其媒体基础等效。 媒体基础 API 已直接映射到 EME,如下图所示:
使用 API 映射,可以直接在 MSE/EME 功能上构建 Microsoft Win32 桌面应用程序,并且还允许第三方浏览器实现这些功能。 下表列出了与 EME 接口对应的特定媒体基础 MediaEngine API:
下表显示了从 MSE(采用 JavaScript)映射到媒体基础 MediaEngine(采用 C++)的 API。
JavaScript (MSE) | MFMediaEngine C++ |
---|---|
[构造函数] | IMFMediaEngineClassFactoryEx::CreateMediaSourceExtension |
MediaSource | IMFMediaSourceExtension |
MediaSource.sourceBuffers | IMFMediaSourceExtension::GetSourceBuffers |
MediaSource.activeSourceBuffers | IMFMediaSourceExtension::GetActiveSourceBuffers |
MediaSource.readyState | IMFMediaSourceExtension::GetReadyState |
MediaSource.duration | IMFMediaSourceExtension::GetDuration IMFMediaSourceExtension::SetDuration |
MediaSource.addSourceBuffer | IMFMediaSourceExtension::AddSourceBuffer |
MediaSource.removeSourceBuffer | IMFMediaSourceExtension::RemoveSourceBuffer |
MediaSource.endOfStream | IMFMediaSourceExtension::SetEndOfStream |
MediaSource.isTypeSupported | IMFMediaSourceExtension::IsTypeSupported |
SourceBuffer | IMFSourceBuffer |
SourceBuffer.updating | IMFSourceBuffer::GetUpdating |
SourceBuffer.buffered | IMFSourceBuffer::GetBuffered |
SourceBuffer.timestampOffset | IMFSourceBuffer::GetTimeStampOffset IMFSourceBuffer::SetTimeStampOffset |
SourceBuffer.audioTracks | 媒体基础中无等效 |
SourceBuffer.appendWindowStart; | IMFSourceBuffer::GetAppendWindowStart IMFSourceBuffer::SetAppendWindowStart |
SourceBuffer.appendWindowEnd | IMFSourceBuffer::GetAppendWindowEnd IMFSourceBuffer::SetAppendWindowEnd |
SourceBuffer.appendBuffer(ArrayBuffer data) | IMFSourceBuffer::Append |
SourceBuffer.appendBufferArrayBufferView data) | IMFSourceBuffer::Append |
SourceBuffer.appendStream | IMFSourceBuffer::AppendByteStream |
SourceBuffer.abort | IMFSourceBuffer::Abort |
SourceBuffer.remove | IMFSourceBuffer::Remove |
SourceBufferList | IMFSourceBufferList |
SourceBufferList.length | IMFSourceBufferList::GetLength |
getter SourceBuffer | IMFSourceBufferList::GetSourceBuffer |
VideoPlaybackQuality | IMFMEdiaEngineEx::GetStatistics |
VideoPlaybackQuality.creationTime | 无媒体基础等效 |
VideoPlaybackQuality.totalVideoFrames | MF_MEDIA_ENGINE_STATISTIC_FRAMES_RENDERED + MF_MEDIA_ENGINE_STATISTIC_FRAMES_DROPPED 这些标记在 MF_MEDIA_ENGINE_STATISTIC 中定义 |
VideoPlaybackQuality.droppedVideoFrames | MF_MEDIA_ENGINE_STATISTIC_FRAMES_DROPPED 此标记在 MF_MEDIA_ENGINE_STATISTIC 中定义。 |
VideoPlaybackQuality.totalFrameDelay | MF_MEDIA_ENGINE_STATISTIC_TOTAL_FRAME_DELAY 此标记在 MF_MEDIA_ENGINE_STATISTIC 中定义。 |
DOMString URL.createObjectURL(MediaSource mediaSource) | 媒体基础中无等效 |
HTMLVideoElement .getVideoPlaybackQuality | 请参阅以上的 VideoPlaybackQuality 说明 |
AudioTrack.kind | 无媒体基础等效 |
AudioTrack.language | IMFMediaEngineEx::GetStreamAttribute 注意,将 MF_SD_LANGUAGE 作为 guidMFAttribute 参数的值传递。 |
AudioTrack.sourceBuffer | IMFMediaSourceExtension::GetSourceBuffer |
Events by target | |
MediaSource.sourceopen | IMFMediaSourceExtensionNotify |
MediaSource.sourceended | IMFMediaSourceExtensionNotify::OnSourceEnded |
MediaSource.sourceclose | IMFMediaSourceExtensionNotify::OnSourceClose |
SourceBuffer.updatestart | IMFSourceBufferNotify::OnUpdateStart |
SourceBuffer.update | IMFSourceBufferNotify::OnUpdate |
SourceBuffer.updateend | IMFSourceBufferNotif::OnUpdateEnd |
SourceBuffer.error | IMFSourceBufferNotify::OnError |
SourceBuffer.abort | IMFSourceBufferNotify::OnAbort |
SourceBufferList.addsourcebuffer | IMFBufferListNotify::OnAddSourceBuffer |
SourceBufferList.removesourcebuffer | IMFBufferListNotify::OnRemoveSourceBuffer |
下表显示了从 EME(采用 JavaScript)映射到媒体基础 MediaEngine(采用 C++)的 API。
JavaScript (MSE) | MFMediaEngine C++ |
---|---|
HTMLMediaElement.msKeys | IMFMediaEngineEME::get_Keys |
HTMLMediaElement.msSetMediaKeys | IMFMediaEngineEME::SetMediaKeys |
onmsneedkey | |
[构造函数] | IMFMediaEngineClassFactory2::CreateMediaKeys2 |
MSMediaKeys | IMFMediaKeys |
MSMediaKeys.keySystem | IMFMediaKeys::get_KeySystem |
MSMediaKeys.createSession | IMFMediaKeys::CreateSession |
MSMediaKeys.isTypeSupported | IMFMediaEngineClassFactoryEx::IsTypeSupported |
IMFMediaKeys::GetSuspendNotify | |
IMFMediaKeys::Shutdown | |
MediaKeySession | IMFMediaKeySession |
MediaKeySession.error | IMFMediaKeySession::GetError |
MediaKeySession.keySystem | IMFMediaKeySession::get_KeySystem |
MediaKeySession.sessionId | IMFMediaKeySession::get_SessionId |
MediaKeySession.update | IMFMediaKeySession::Update |
MediaKeySession.close | IMFMediaKeySession::Close |
HTMLSourceElement.keySystem | IMFMediaEngineSrcElementsEx::GetKeySystem |
事件接口增项 | |
MediaKeyMessageEvent | 等效于 IMFMediaKeySessionNotify |
MediaKeyMessageEvent.message | |
MediaKeyMessageEvent.destinationURL | |
MediaKeyNeededEvent | 等效于 IMFMediaEngineNeedKeyNotify |
MediaKeyNeededEvent.initData | |
事件 | |
keyadded | IMFMediaKeySessionNotify::KeyAdded |
keyerror | IMFMediaKeySessionNotify::KeyError |
keymessage | IMFMediaKeySessionNotify::KeyMessage |
msneedkey | IMFMediaEngineNeedKeyNotify::NeedKey |
IMFMediaSourceExtension 对象
将 MSE API 映射到其媒体基础等效后,浏览器必须将 IMFMediaSourceExtension 对象附加到元素中。 执行此操作的一个方法如下:
-
根据 W3C MSE 标准实现 URL.createObjectURL (MediaSource mediaSource)。
-
将 MediaSource 对象 URL 设置为媒体元素的源后,通过 IMFMediaEngine::SetSource 方法将 URL 传递到媒体基础。
-
创建媒体引擎的实例时,通过在传递到 IMFMediaEngineClassFactory::CreateInstance 的 IMFAttributes 存储上设置 MF_MEDIA_ENGINE_EXTENSION 属性来传递实现 IMFMediaEngineExtension 的对象。
-
实现 IMFMediaEngineExtension 以致使用 type=MF_OBJECT_MEDIASOURCE 和 MediaSource URL 调用 BeginCreateObject 时会导致通过提供的回调异步返回关联的 IMFMediaSourceExtension 实例。
PlayReady AppX 框架
四个框架会暂存在 Windows 8.1 中。 x86 和 amd64 变体成对出现。 另外,如果要与 Windows 8 Windows 应用商店应用兼容,则需要使用为其保持的特定版本(在系列名称 Microsoft.Media.PlayReadyClient 下)以及使用所添加 EME 功能提供的新版本。
AppX PackageManager 跟踪 AppX 框架上的应用依存关系。 这些框架通常在应用清单中声明,但新体验浏览器会作为桌面应用构建且没有清单选项。 它们必须明确引用框架以通知程序包管理器框架具有需要安装该框架的桌面应用。 这样可确保程序包管理器会保持框架的活动状态,即便需要使用该框架的所有 Windows 8 Windows 应用程序应用都已被删除。
AppX 框架通常会限制为仅供 Windows 应用商店应用使用。 在 Windows 8.1 中,Microsoft PlayReady 应用包可供桌面或新体验桌面浏览器使用。 如果浏览器使用媒体基础 API 实现 EME,则会自动出现此情形。
InPrivate 浏览
IE11 删除了在 In Private 浏览会话过程中获取的 Microsoft PlayReady 许可证。 建议实现 EME 的其他浏览器执行此尝试。
使用新的 Microsoft PlayReady 框架,应用可以为任何会话指定许可证存储位置(也称为确立数据存储或 HDS)。 此默认 HDS 还特定于使用框架的应用,以便其中存储的许可证可由应用隔离。 默认 HDS 还包含 Indiv 数据和可以获取的所有永久性许可证。 鉴于此原因,Microsoft 建议不要删除该 HDS。
IE11 将默认 HDS 用于常规 EME 会话,并且使用 Microsoft PlayReady HDS 路径功能为 In Private 浏览指定单独的 HDS。 这样允许删除 In Private HDS,并且不会对 Indiv 数据或永久性许可证造成任何影响。
浏览器可以使用 cdmStorePath 的可选 IMFMediaEngineClassFactory2::CreateMediaKeys2 参数执行相同的操作来指定 Microsoft PlayReady CDM 的目录路径。
HRESULT CreateMediaKeys2( [annotation("_In_")] BSTR keySystem, [annotation("_In_")] BSTR defaultCdmStorePath, [annotation("_In_opt_")] BSTR inprivateCdmStorePath, [annotation("_COM_Outptr_")] IMFMediaKeys **ppKeys );
当 In Private 会话结束时,Windows Internet Explorer 会删除整个 cdmStorePath 目录。这表示 In Private 过程中存储的所有永久性许可证都会被删除。
选项卡挂起
IE11 实现选项卡挂起以在用户使用浏览器时帮助最小化电源消耗。
使用选项卡挂起,可针对后台操作单独管理浏览器选项卡。 使用选项卡挂起,Windows 可在浏览器打开多个选项卡时管理 CPU 需求。
某些主要系统要求先通知,然后挂起,包括 Microsoft PlayReady。 挂起选项卡之前,浏览器应为选项卡中运行的每个唯一主要系统执行以下步骤:
-
为框架进程中的主要系统创建新的媒体密钥实例。
-
调用 IMFMediaKeys::GetSuspendNotify 可检索主要系统的挂起处理程序。 主要系统可以在不许要使用挂起处理程序时返回 HRESULT E_NOTIMPL。
-
在挂起选项卡之前,请调用 IMFCdmSuspendNotify::Begin。 如果挂起处理程序返回除 S_OK 之外的任何内容,则中止选项卡挂起,然后在几分钟后重试。
-
挂起选项卡之后,请调用 IMFCdmSuspendNotify::End。
-
发布由框架进程创建的挂起处理程序和媒体密钥。