使用 Windows Media 格式(WMF)捕获桌面
我正在使用 Windows Media Format SDK 来捕获实时桌面并将其保存在 WMV 文件中(实际上这是我的项目的过度简化,但这是相关部分)。 对于编码,我使用 Windows Media Video 9 Screen 编解码器,因为它对于屏幕捕获非常有效,而且几乎每个人都可以使用它而无需安装任何东西,因为该编解码器包含在 Windows Media Player 9 运行时(包含在 Windows XP SP1 中)中。
我正在使用 GDI 函数制作位图屏幕截图,并将这些位图提供给编码器。 正如您所猜测的,使用 GDI 进行屏幕截图速度很慢,而且我看不到屏幕光标,我必须手动将其添加到位图中。 我最初获得的位图是 DDB,我需要将它们转换为 DIB 以便编码器理解(RGB 输入),这需要更多时间。
触发探查器显示大约 50% 的时间花在编码器 WMVCORE.DLL 上。 当然,这是可以预料的,因为编码是 CPU 密集型的。
问题是,有一个名为 Windows Media Encoder 的东西附带 SDK,可以使用所需的编解码器以更简单、更 CPU 友好的方式进行屏幕捕获。
WME 基于 WMF。 它是一个更高级别的库,并且还具有 .NET 绑定。 我无法在我的项目中使用它,因为这会带来我必须避免的不需要的依赖项。
我问的是 WME 用于将样本数据馈送到 WMV 编码器的方法。 使用 WME 进行编码与使用 WMF 的应用程序进行编码完全相同。 WME 比我的应用程序更高效,因为它有一种更有效的方式将视频数据馈送到编码器。 它不依赖于缓慢的 GDI 函数和 DDB->DIB 转换。
它是如何完成的?
I am using Windows Media Format SDK to capture the desktop in real time and save it in a WMV file (actually this is an oversimplification of my project, but this is the relevant part). For encoding, I am using the Windows Media Video 9 Screen codec because it is very efficient for screen captures and because it is available to practically everybody without the need to install anything, as the codec is included with Windows Media Player 9 runtime (included in Windows XP SP1).
I am making BITMAP screen shots using the GDI functions and feed those BITMAPs to the encoder. As you can guess, taking screen shots with GDI is slow, and I don't get the screen cursor, which I have to add manually to the BITMAPs. The BITMAPs I get initially are DDBs, and I need to convert those to DIBs for the encoder to understand (RGB input), and this takes more time.
Firing a profiler shows that about 50% of the time is spent in WMVCORE.DLL, the encoder. This is to be expected, of course as the encoding is CPU intensive.
The thing is, there is something called Windows Media Encoder that comes with a SDK, and can do screen capture using the desired codec in a simpler, and more CPU friendly way.
The WME is based on WMF. It's a higher lever library and also has .NET bindings. I can't use it in my project because this brings unwanted dependencies that I have to avoid.
I am asking about the method WME uses for feeding sample data to the WMV encoder. The encoding takes place with WME exactly like it takes place with my application that uses WMF. WME is more efficient than my application because it has a much more efficient way of feeding video data to the encoder. It doesn't rely on slow GDI functions and DDB->DIB conversions.
How is it done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否检查过 BB FlashBack 库?
我也在寻找类似的东西,并且刚刚开始评估 BB FlashBack 库。
我不确定外部依赖项或安装足迹。 它似乎必须安装一个专有的编解码器,但编解码器的安装可以通过公开的 BB FlashBack API 来处理。
请注意,存在许可限制(许可证密钥的运行时设置……)
如果您想在提交许可下载之前评估 API,我可以通过电子邮件向您发送 SDK 中的 CHM。
我正在评估的事情:
正确捕获 WPF 视图
鼠标光标跟踪
存储影片的大小
如何在没有专有编解码器的情况下显示存储的电影(即SWF导出)
--Batgar
Have you checked out the BB FlashBack library?
I am on a similar hunt, and I have just started evaluating the BB FlashBack library.
I am not sure about the external dependencies or install footprint. It appears to have a proprietary codec that has to be installed, but the installation of the codec can be handled by the exposed BB FlashBack API.
Beware, there are licensing restrictions (Runtime setting of license keys, ...)
I can send you the CHM from the SDK via e-mail if you want to evaluate the API before committing to a licensed download.
Things I am in the midst of evaluating:
Proper captures of WPF views
mouse cursor tracking
Size of stored movie
How to display stored movie without proprietary codec (i.e. SWF export)
--Batgar
我已经很久没有完成任何 Win32 编码了,但是据我所知,WMF 作为一种格式基本上是 GDI 命令及其参数的列表,这可以解释为什么编码效率更高......
您可能需要挂钩进入顶级 GDI 上下文(我猜就像远程桌面所做的那样)并捕获调用的 GDI 命令。 我似乎记得有某种方法可以创建 WMF 输出 GDI 上下文,这意味着您可以以某种方式将调用委托给它。
我在这里猜测,但您可能能够在 Windows 项目的 TightVNC/QuickVNC 中找到上述示例代码,因为它们必须执行类似的操作才能以有效的方式捕获屏幕上的更改。
It's been ages since I've done any Win32 coding, but AFAIK, WMF as a format is basically a list of GDI commands and their parameters which would explain why it is much more efficient to encode...
You'd probably need to hook into the top level GDI context (just as Remote Desktop does, I guess) and capture the GDI commands as they are called. I seem to remember there being some way of creating a WMF output GDI context which means you may be able to just delegate calls to it in some way.
I'm guessing here, but you may be able to find example code for the above in the TightVNC/QuickVNC for Windows projects as they would have to do something like that to capture changes on screen in an efficient way.
CamStudio 是一个已经存在多年的 GPL 截屏应用程序(商业化,后来开放 srcd)的源代码可能有用吗?
http://sourceforge.net/project/showfiles.php?group_id=131922
我建议也看看 VNC 客户端的内部结构,尽管它们可能非常简单(我认为只需抓取屏幕截图,然后对自上次捕获以来已更改的图块进行 jpg 处理)。
如果 WMV9 太占用 CPU 资源,您可能会考虑不使用 WMV9 作为即时编码的编码器? 也许使用 HyperCam 使用的较旧的、效率较低的压缩器(如 MS RLE),然后压缩为 WMV? 至少从 Win2000 开始,MS RLE 就已经是默认安装了,我相信:
http://wiki.multimedia.cx/index.php?title=Microsoft_RLE
CamStudio 的无损编解码器是 GPL(与上面的链接相同),它提供了相当好的压缩(尽管您需要在安装程序中捆绑 dll)并且可以即时使用,它在所有现代系统上都可以很好地进行高压缩。
The source to CamStudio, a GPL'd screencasting app that's been around for years (commercially and then open-srcd later) might be useful?
http://sourceforge.net/project/showfiles.php?group_id=131922
I'd suggest looking at the guts of VNC clients too, though they're probably very simplistic (I think just grabbing screenshots then jpg'ing the tiles that have changed since the last capture).
You might want to consider not using WMV9 as the encoder for on-the-fly encoding if it is too cpu-heavy? Maybe use an older, less efficient compressor (like MS RLE) as used by HyperCam and then compress to WMV afterwards? MS RLE has been a default install since at least Win2000 I believe:
http://wiki.multimedia.cx/index.php?title=Microsoft_RLE
CamStudio's Lossless codec is GPL (same link as above), that offers pretty good compression (though you'd need to bundle the dll in your installer) and could be used on the fly, it works well with high compression on all modern systems.