Simple, free screen capture with FFMPEG

Once you have ffmpeg installed and added to your PATH (see my previous guide), screen capture with audio is simple. Well, hopefully it’s simple following these directions, it took a while for me to figure it out.

On Windows 7/8/10

Windows uses a capture device called ‘gdigrab’ to do screen capture, and ‘dshow’ to capture audio and video input devices. Open your powershell, and type the following command to find out what your audio device is called.

ffmpeg -list_devices true -f dshow -i dummy

You should see output like the following. Notice in the sound settings on the right (you can get here by right clicking your volume icon on the toolbar and listing Playback or Recording devices), two devices are listed. Unless the device is plugged in and ready to go, ffmpeg doesn’t see it. It also truncates the name, so “Microphone (High Definition Audio Device)” becomes “Microphone (High Definition Aud” — it’s this exact string, quotes and all, that gets returned in the command line that’s important for the audio capture command.

Once you know what your audio device is called, you can stream it as input alongside your screen capture. First, though, I highly recommend changing your screen resolution to 1280 x 720 or 1920 x 1080, the high-def resolutions that youtube supports. This will simplify the transcoding process and result in a sharp video (as opposed to asking FFMPEG to downsample my 3000 x 2000 screen, which would screw up the aspect ratio. Much simpler to just record a screen already set to a useful HD resolution.) When you’re all set to record, run this command (with your audio device after -i audio:)

ffmpeg -f gdigrab -i desktop -f dshow -i audio="Microphone (High Definition Aud" -vcodec libx264 YOUR_NAME_HERE.mp4

That runs ffmpeg with the desktop as one input (-i), and the microphone as the second input (-i). The vcodec libx264 flag uses the h.264 mpeg encoder, which I found necessary to get a sharp, unpixelated video.

If you have no interest in recording audio, you can omit the second input device, and your command will look something like:

ffmpeg -f gdigrab -i desktop -vcodec libx264 YOUR_NAME_HERE.mp4

If you’re counting pennies and want to limit your file size, using the framerate flag (-framerate) to grab 5 fps or 10 fps is a great way to do so. Lowering your screen resolution is another option to limit your file size. The official documentation has a million options to peruse.

ffmpeg -f gdigrab -i desktop -framerate 10 -vcodec libx264 YOUR_NAME_HERE.mp4

Once you’ve started recording, your powershell will fill with status updates and error messages. You can minimize it while you work. When you want to stop recording, bring the same powershell back up and hit ‘Q’ on your keyboard to cancel the operation. Powershell may ‘hang’ (aka lock up) for a moment or two while it finishing processing. The video will now exist as the named mp4. Oh, and this happens in whatever directory powershell is focused on, unless you specify a full path for that mp4 (ex. C:UsersFabLabVideosvid.mp4 ).

After hitting ‘q’ to quit (you might hit it twice if it doesn’t respond) you’ll see this:

“exiting normally” — good sign! Go into the directory you ran the command in (C:UsersColten Jackson for me) and find your video. Should be ready to upload to youtube right away!

High Quality Gifs with FFMPEG

After getting FFMPEG installed, let’s try it out on a MOV downloaded from my google photos account:

ffmpeg -i MVI_6654.MOV firsttry.gif

We’re calling the ffmpeg program and telling it that MVI_6654.MOV is our input file with the -i flag. the filename at the end defines the conversion and creates the new file, resulting in:

Pretty cool. But I bet I can make it loop nicely by just using the first few seconds, so we use the duration flag, -t and specify the duration in seconds.

ffmpeg -t 2 -i MVI_6654.MOV secondtry.gif

So it loops! kinda slow tho, maybe we can drop every other frame? A-ha. Thanks to the -r flag, we can choose a frame rate for the output (note that these options do different things based on their order. -t is used before the -i input, -r is used after the input, so it affects the output.)

ffmpeg -t 2 -i MVI_6654.MOV -r “15” thirdtry.gif

That’s more like it. As an added benefit, the file is now 2 megabytes instead of 8 megabytes. I’ve got another one to convert that has kind of a long input video, so I’m going to specify a time to start the gif as well as the duration. The -ss flag defines the starting point. Oh yeah, and your seconds can be decimals. If you have a longer video and want to define the starting position in hours, minutes, seconds, you can use “hh:mm:ss” format, like “00:00:03” instead of “3”

ffmpeg -t 3 -ss 0.5 -i MVI_6663.MOV -r “15” fourthtry.gif

This has been pretty simple, but I know I’ve seen better looking gifs. Let’s find out how to make it look more like a video…

Learned a lot from this blog about the color palette algorithms.

Found a relatively simple example on stackoverflow.

We have to generate a custom color palette so we don’t waste space storing colors we don’t use (the gif file format is limited to 256 colors):

ffmpeg -ss 2.6 -t 1.3 -i MVI_7035.MOV -vf  fps=15,scale=320:-1:flags=lanczos,palettegen palette.png

You should recognize what -ss, -t, and -i do here, -vf is a way to invoke filters on our video. so we can describe fps and scale here. Hm. I’ll admit I don’t know what -1 does. But the flags describe what algorithm to use, more info in that blog. So that generates palette.png which we can use in our 2nd line in terminal (by the way, the backslash at the end of the line is if you run out of space and need to keep typing, hit backslash and return and you can keep going on a new line before hitting return to complete the command.)

ffmpeg -ss 2.6 -t 1.3 -i MVI_7035.MOV -i palette.png 
-filter_complex “fps=15,scale=400:-1:flags=lanczos[x];[x][1:v]paletteuse” sixthtry.gif

This uses our .MOV as an input but has a second -i flag to use palette.png as a 2nd input. Then, ok, I copy pasted the rest of it, but I’m happy enough with what this produces that I’ll stop asking questions 😀

Let me know if there’s anything I can explain in more detail, but don’t ask me for help installing things, just google it!

Side by side comparison of easy, default color palettes and head-scratching custom color palettes

I’d like to revisit this with more general advice and showing off other aspects of ffmpeg, but in the meantime here’s articles that others’ found helpful.