从 Windows 中的 OpenGL 窗口捕获视频
我应该为我的用户提供一种从我的 OpenGL 应用程序的主窗口捕获视频剪辑的非常简单的方法.我正在考虑添加用于启动和停止捕获的按钮和/或键盘快捷键;开始时,我可以要求提供文件名和其他选项(如果有).它必须在 Windows (XP/Vista) 中运行,但我也不想关闭迄今为止我能够保持打开的 Linux 门.
该应用程序使用 OpenGL 片段和着色器程序,这些效果是我在最终视频中绝对需要的.
在我看来,甚至可能有几种不同的方法可以满足我的要求(但我真的不知道应该从哪里开始):
一个编码库,具有 startRecording(filename)、stopRecording 和 captureFrame 等功能.我可以在渲染每一帧(或每第二/第三/无论如何)之后调用 captureFrame().如果这样做会使我的程序运行速度变慢,那其实不是问题.
一个独立的外部程序,可以通过我的应用程序进行编程控制.毕竟,一个无法控制的独立程序几乎可以满足我的需求……但正如前面所说,它应该让用户操作起来非常简单,而且我也很欣赏无缝;我的应用程序通常全屏运行.此外,应该可以作为我的应用程序安装包的一部分分发,我目前使用 NSIS 准备.
使用 Windows API 逐帧捕获屏幕截图,然后使用(例如)此处提到的库.找到如何在 Windows 中捕获屏幕截图的示例似乎很容易;但是,我希望有一个解决方案,它不会真正强迫我在 WinAPI 级别上弄得非常脏.
使用 OpenGL 渲染到屏幕外目标,然后使用库生成视频.我不知道这是否可能,而且恐怕无论如何这都不是最不痛苦的途径.特别是,我不希望实际渲染根据是否正在捕获视频而采用不同的执行路径.此外,我会避免在正常的非捕获模式下可能会降低帧速率的任何事情.
如果解决方案在任何意义上都是免费的,那就太好了,但这并不是绝对的要求.一般来说,膨胀越少越好.另一方面,由于这个问题之外的原因,不幸的是,我无法链接任何仅 GPL 的代码.
关于文件格式,我不能指望我的用户开始搜索任何编解码器,但只要显示视频对于基本级别的 Windows 用户来说足够容易,我不会真的很在意格式是什么.不过如果能控制输出的压缩质量就好了.
澄清一下:我不需要从摄像机等外部设备捕获视频,我也对鼠标移动不感兴趣,即使获取它们也不会造成伤害.对音频没有要求;该应用程序不会发出任何噪音.
我使用 Visual Studio 2008 编写 C++,为此应用程序也利用了 GLUT 和 GLUI.我对 C++ 和库中的链接以及诸如此类的东西有深入的了解,但另一方面,OpenGL 对我来说还是很新的:到目前为止,我真的只学到了真正完成工作所需的部分.>
我不需要非常紧急的解决方案,所以请慢慢来:)
解决方案这里有两个不同的问题 - 如何从 OpenGL 应用程序中抓取帧,以及如何将它们转换为电影文件.
第一个问题很简单;您只需使用 glReadPixels() 抓取每一帧(如果需要性能,可以通过 PBO).
第二个问题有点难,因为跨平台解决方案 (ffmpeg) 往往是 GPL 或 LGPL.您的项目可以接受 LGPL 吗?Windows 的方式(DirectShow)使用起来有点头疼.
由于 LGPL 没问题,您可以使用 ffmpeg,请参阅 此处 了解如何编码视频的示例.
I am supposed to provide my users a really simple way of capturing video clips out of my OpenGL application's main window. I am thinking of adding buttons and/or keyboard shortcuts for starting and stopping the capture; when starting, I could ask for a filename and other options, if any. It has to run in Windows (XP/Vista), but I also wouldn't like to close the Linux door which I've so far been able to keep open.
The application uses OpenGL fragment and shader programs, the effects due to which I absolutely need to have in the eventual videos.
It looks to me like there might be even several different approaches that could potentially fulfill my requirements (but I don't really know where I should start):
An encoding library with functions like startRecording(filename), stopRecording, and captureFrame. I could call captureFrame() after every frame rendered (or every second/third/whatever). If doing so makes my program run slower, it's not really a problem.
A standalone external program that can be programmatically controlled from my application. After all, a standalone program that can not be controlled almost does what I need... But as said, it should be really simple for the users to operate, and I would appreciate seamlessness as well; my application typically runs full-screen. Additionally, it should be possible to distribute as part of the installation package for my application, which I currently prepare using NSIS.
Use the Windows API to capture screenshots frame-by-frame, then employ (for example) one of the libraries mentioned here. It seems to be easy enough to find examples of how to capture screenshots in Windows; however, I would love a solution which doesn't really force me to get my hands super-dirty on the WinAPI level.
Use OpenGL to render into an offscreen target, then use a library to produce the video. I don't know if this is even possible, and I'm afraid it might not be the path of least pain anyway. In particular, I would not like the actual rendering to take a different execution path depending on whether video is being captured or not. Additionally, I would avoid anything that might decrease the frame rate in the normal, non-capture mode.
If the solution were free in either sense of the word, then that would be great, but it's not really an absolute requirement. In general, the less bloat there is, the better. On the other hand, for reasons beyond this question, I cannot link in any GPL-only code, unfortunately.
Regarding the file format, I cannot expect my users to start googling for any codecs, but as long as also displaying the videos is easy enough for a basic-level Windows user, I don't really care what the format is. However, it would be great if it were possible to control the compression quality of the output.
Just to clarify: I don't need to capture video from an external device like camcorder, nor am I really interested in mouse movements, even though getting them does not harm either. There are no requirements regarding audio; the application makes no noise whatsoever.
I write C++ using Visual Studio 2008, for this very application also taking benefit of GLUT and GLUI. I have a solid understanding regarding C++ and linking in libraries and that sort of stuff, but on the other hand OpenGL is quite new for me: so far, I've really only learnt the necessary bits to actually get my job done.
I don't need a solution super-urgently, so feel free to take your time :)
解决方案There are two different questions here - how to grab frames from an OpenGL application, and how to turn them into a movie file.
The first question is easy enough; you just grab each frame with glReadPixels() (via a PBO if you need the performance).
The second question is a little harder since the cross-platform solutions (ffmpeg) tend to be GPL'd or LGPL'd. Is LGPL acceptable for your project? The Windows way of doing this (DirectShow) is a bit of a headache to use.
Edit: Since LGPL is ok and you can use ffmpeg, see here for an example of how to encode video.
相关文章