我应该为我的用户提供一种非常简单的方法,从我的 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,请参阅 这里 有关如何对视频进行编码的示例。

其他提示

看起来确实与合并到 AVI 中非常相关(正如 Andrew 所建议的),但是我真的希望避免 LPBITMAPINFOHEADER 等。

感谢您的回答,如果有任何成功,我会报告:)

与此同时,对原始帧进行编码的其他技巧 glReadPixels 进入视频剪辑将不胜感激。

编辑: 到目前为止,Mike F 建议的 ffmpeg 似乎是最佳选择。然而,我还没有进入实际的实施阶段,但希望这种情况在不久的将来会改变!

最简单的选择是保存应用程序中的每个渲染帧,然后将它们合并到 AVI 中。当您拥有 AVI 时,有许多可用的库可以将其转换为更优化的格式,或者可能完全跳过 AVI 步骤。

在获取每一帧方面,您可以按照您的建议通过渲染为屏幕外纹理来完成此操作,或者如果您的硬件支持此操作,则可以直接使用后缓冲区作为源。如果不对帧率造成严重影响,执行其中任何一项(并保存每一帧)都会很困难。

如果您的应用程序是确定性的,您可以将用户操作“记录”为一系列输入,然后使用导出模式将这些操作顺序渲染到屏幕外表面以生成 AVI。

我必须创建一个将 OpenGL 渲染记录到视频中的演示项目。我用了 glReadPixels 获取像素数据并使用 OpenCV 创建视频 cvWriteFrame. 。OpenCV 允许您使用 divx 甚至 x264/vp8(编译有 ffmpeg)进行编写。

我的博客文章中有更详细的文章以及示例项目。http://tommy.chheng.com/2013/09/09/encode-opengl-to-video-with-opencv/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top