<p>It's not too difficult to set up your app to stream frames directly to ffmpeg. <a href="http://blog.mmacklin.com/2013/06/11/real-time-video-capture-with-ffmpeg/" rel="noreferrer">This blog post by Miles Macklin shows how</a>, and I've used this method in my own apps.</p>

<p>You spawn ffmpeg as a child process from your app, and at the end of each frame you just read back the GL framebuffer and write its contents to ffmpeg's stdin. The relevant code bits are excerpted here.</p>

<p>Initializing ffmpeg:</p>

<pre><code>// start ffmpeg telling it to expect raw rgba 720p-60hz frames
// -i - tells it to read frames from stdin
const char* cmd = "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s 1280x720 -i - "
                  "-threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip output.mp4";

// open pipe to ffmpeg's stdin in binary write mode
FILE* ffmpeg = _popen(cmd, "wb");
</code></pre>

<p>Writing a frame:</p>

<pre><code>glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg);
</code></pre>

<p>You can adjust the quality by altering the <code>-crf</code> option in the command line (lower numbers are better quality). Don't forget to change the resolution (<code>-s</code>) and framerate (<code>-r</code>) to match what you want, as well.</p>

<p>Depending on the quality, how fast your PC is, etc, it might not quite work in real-time. It's a good idea to set up your app to use a fixed per-frame timestep when you're in video capture mode, so the resulting animation doesn't depend on how much slowdown there was in the capture process.</p>

CC BY-SA 3.0
2017-11-25T16:06:28.200Z
`fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg);` is throwing a Seg fault
mikeglaz
CC BY-SA 3.0
2017-09-16T16:24:07.580Z
2017-09-16T16:24:07.580Z
Nathan Reed
<p>That is not an easy question to answer. First of all you will have to understand the MP4 format. And secondly you will have to keep track of every frame being displayed by OpenGL. So my suggestion to maximize performance is to keep all of the frame data after every frame in a file on the hard drive and after the animation read all of the files and write to an MP4 file.</p>

CC BY-SA 3.0
2017-09-16T08:01:01.007Z
2017-09-16T08:01:01.007Z
Owen Thompson
<p>Does anyone know how to do run an OpenGL animation and then convert it into a mp4 movie?  I've been trying with apitrace and ffmpeg but I get horrible quality output...</p>

<opengl>
OpenGL animation - turn into mp4 movie
mikeglaz
# OpenGL animation - turn into mp4 movie

(Asked by: username_0 on 2017-09-13)

Does anyone know how to do run an OpenGL animation and then convert it into a mp4 movie? I've been trying with apitrace and ffmpeg but I get horrible quality output...

**Tags:** opengl


---

## 2 answers

### Answer by username_1 on 2017-09-16. Score: 6

It's not too difficult to set up your app to stream frames directly to ffmpeg. [This blog post by Miles Macklin shows how](http://blog.mmacklin.com/2013/06/11/real-time-video-capture-with-ffmpeg/), and I've used this method in my own apps.

You spawn ffmpeg as a child process from your app, and at the end of each frame you just read back the GL framebuffer and write its contents to ffmpeg's stdin. The relevant code bits are excerpted here.

Initializing ffmpeg:

```
// start ffmpeg telling it to expect raw rgba 720p-60hz frames
// -i - tells it to read frames from stdin
const char* cmd = "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s 1280x720 -i - "
                  "-threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip output.mp4";

// open pipe to ffmpeg's stdin in binary write mode
FILE* ffmpeg = _popen(cmd, "wb");

```

Writing a frame:

```
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg);

```

You can adjust the quality by altering the `-crf` option in the command line (lower numbers are better quality). Don't forget to change the resolution (`-s`) and framerate (`-r`) to match what you want, as well.

Depending on the quality, how fast your PC is, etc, it might not quite work in real-time. It's a good idea to set up your app to use a fixed per-frame timestep when you're in video capture mode, so the resulting animation doesn't depend on how much slowdown there was in the capture process.

> **Comments:**
> **username_0**: `fwrite(buffer, sizeof(int)*width*height, 1, ffmpeg);` is throwing a Seg fault  

---

### Answer by username_2 on 2017-09-16. Score: 0

That is not an easy question to answer. First of all you will have to understand the MP4 format. And secondly you will have to keep track of every frame being displayed by OpenGL. So my suggestion to maximize performance is to keep all of the frame data after every frame in a file on the hard drive and after the animation read all of the files and write to an MP4 file.


---

