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