首先,当您使用 printscreen 或其他屏幕捕获技术时,VLC 的内容没有被捕获的原因是(至少在旧版本的 Windows 上)它们使用“覆盖”来呈现视频。这是一种特殊的 GPU 构造,允许渲染到正常屏幕表面上方的虚拟“平面”。由于这绕过了其他所有内容并直接进入 GPU,因此没有任何直接的方法可以捕获它。注意:在 Windows 的最后几个版本中,有关覆盖的规则发生了很大变化。应用程序不能假设支持 D3D9/DDraw 覆盖,并且应用程序现在不应该使用它们,因为系统具有更好的方法来呈现具有相同高性能的内容。
Direct3D 9 叠加层
如果您使用 Direct3D 9 显示视频内容,您也可以使用覆盖。有关如何执行此操作的信息,请参阅MSDN 上的此页面。D3D9 覆盖的使用有很多限制,而且很多硬件都不支持它们,所以我将描述一些其他方法。
此技术不会阻止其他应用程序将它们注入您的地址空间并捕获您的礼物。此外,由于某些硬件不支持它并且某些捕获 API 实际上禁用了覆盖,因此它不能提供非常强大的保护保证。
基于 GPU 的内容保护
如果您有大量时间了解 GPU 内容保护并且您知道您将显示受 DRM 保护的非标准视频格式,您可以使用 GPU 内容保护来滚动您自己的受保护媒体路径。我不是这方面的专家,也很少有专家。我不会推荐这个,但我想指出这一点。MSDN 上的这个页面讨论了它是如何在 Direct3D 9 中实现的,而另一个页面则讨论了它是如何使用 Direct3D 11 实现的。
这种技术为内容未被捕获提供了强有力的保证,因为密钥交换几乎完全通过硬件(例如 HDCP)进行。
媒体基金会受保护的媒体路径 (PMP)
如果您使用受良好支持的基于 DRM 的媒体格式显示视频,则可以使用 Media Foundation 的受保护的媒体路径,它利用前面描述的基于 GPU 的内容保护。它还将大部分功能封装在一个单独的受保护进程中,其他应用程序无法拦截或以其他方式与之交互。如果有人尝试安装经过测试签名的驱动程序或以其他方式注入未经受信任的根授权进行代码签名的二进制文件,Windows 将不允许解密内容,并且您的内容将保持安全。这种技术提供了内容未被捕获的有力保证。Netflix 在 Windows、Blueray 播放器和其他设备上使用此功能。
DXGI 交换链标志
假设您使用 Direct3D 10.x/11.x 呈现内容(希望现在您使用的是 2014 年的 D3D 9),您可以在交换链上使用许多标志来锁定您的内容。
DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT
如果系统没有 HDCP 或类似 HDCP 的输出保护,您可以传入交换链标志以使交换链创建失败。对于您的目的而言,这可能不是必需的,但如果您担心人们捕获 HDMI 或模拟输出,这很好。
你绝对想要的标志叫做DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY
. 这可以防止所有屏幕捕获 API 看到您的交换链。它对他们来说只是一个黑色的矩形。
有关所有 DXGI 交换链标志,请参阅此页面。
这种技术不能提供基于 GPU 的内容保护所提供的强有力的保证,但是如果您非常确信其他应用程序不会做一些疯狂的事情,例如将自己注入您的地址空间并挂钩您当前的调用,那么您可以有信心这可以防止其他任何人看到您的内容(当然除了显示器)。
全窗口保护
有时您可能想要保护的不仅仅是 DXGI 呈现的内容。在这种情况下,您实际上可以使用类似的机制来简单地保护整个窗口不被各种屏幕捕获技术捕获。这是一个名为SetWindowDisplayAffinity
. 它在强度和功能上等同于DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY
为交换链传递标志,但它也保护使用 GDI、较旧的 DirectX 技术等呈现的内容。传递WDA_MONITOR
标志以启用对给定 HWND 的保护,或传递WDA_NONE
以禁用保护。
为了全面披露,我在 Microsoft 的团队工作,负责处理显示逻辑,包括某些形式的屏幕捕获和内容保护。