12

我应该为我的用户提供一种非常简单的方法来从我的 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 对我来说还是很新的:到目前为止,我真的只学到了实际完成工作所需的一些知识。

我不需要非常紧急的解决方案,所以请慢慢来:)

4

4 回答 4

9

这里有两个不同的问题——如何从 OpenGL 应用程序中抓取帧,以及如何将它们转换为电影文件。

第一个问题很简单;您只需使用 glReadPixels() 抓取每一帧(如果您需要性能,请通过 PBO)。

第二个问题有点困难,因为跨平台解决方案 (ffmpeg) 往往是 GPL 或 LGPL。您的项目可以接受 LGPL 吗?执行此操作的 Windows 方式 (DirectShow) 使用起来有点令人头疼。

编辑:由于 LGPL 没问题,您可以使用 ffmpeg,请参阅此处了解如何编码视频的示例。

于 2008-09-30T20:14:45.470 回答
1

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

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

glReadPixels同时,将不胜感激将原始帧编码为视频剪辑的其他技巧。

编辑:到目前为止,Mike F 建议的 ffmpeg 似乎是要走的路。但是,我还没有进入实际的实现,但希望在不久的将来会有所改变!

于 2008-09-30T20:50:26.867 回答
0

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

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

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

于 2008-09-30T20:16:17.853 回答
0

我必须创建一个将 OpenGL 渲染录制到视频中的演示项目。我曾经glReadPixels获取像素数据并使用 OpenCV 的cvWriteFrame. OpenCV 让您可以使用 divx 甚至 x264/vp8(编译了 ffmpeg)编写代码。

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

于 2013-09-09T16:56:02.490 回答