FFMpeg does it all. However, the combination of video and audio capture raises some delicate problems. The present article explains all the options and considerations for Windows
Synchronization between Audio and Video
Capturing video from a camera is commonplace. I wanted to capture video from the computer screen, for example, to produce a video lecture. I’ve noticed several CodeProject articles describing different means of capturing everything which happens on the computer screen. I did not found what I wanted. Some solutions are bound to some obsolete video containers or obsolete components, others are over-complicated or don’t work properly.
At the same time, the solution is way simpler and is readily available: compact, open-source, and built for most platforms FFMpeg does it all.
Basically, everything is done using FFMpeg with this command line:
-f dshow -i audio="Stereo Mix (Realtek Audio)" ^
-f gdigrab -itsoffset 00:00:0.6 -i desktop -c:v libx264rgb ^
-framerate 24 -crf 20 -preset ultrafast ^
f “enforce format” options define the methods of capturing video. Unfortunately, these methods and corresponding
-i “input” options are platform-dependent. So far, I’ve sorted out the usage only for Windows, but later may need to do the same with Linux.
The first line after
ffmpeg is optional and defines audio capture, two following lines — video capture. The audio capture depends on the device to be used. Sometimes, this is the audio produced by computer software, and this is the case shown in the command line above. In other cases, we need the capture from a microphone.
First of all, why using H264 (AVC) standard? The answer is: for the same reason as
ultrafast: performance. Usually, we don’t need the best compression, we need the algorithm which gives us good quality but not overwhelms the CPU and other resources. If encoding is slow, it won’t encode frames in time, and it can even delay the computer operation. In this situation, AVC is a very good choice. If you have a better idea, you can always replace the codec (
-c:v) parameter and codec options (next line) with something else.
Naturally, for final production, the resulting video will require transcoding using some more advanced codec with good quality and much better compression. At the time of writing, I strongly recommend the most advanced AOMedia AV1, but it can be something else. Please see FFMpeg documentation.
Video capture parameters:
Constant Rate Factor
crf: valid values: 0-51, 0 is lossless, 23: default, 51: worse possible quality.
framerate; common frame rates: 24, 25, 30, 48, 50, and 60
veryslow; for the specific purpose of capture, we need the operation to be fast enough, caring of the compression factor much less. Perfectly compressed video with the best quality can be achieved after transcoding for production.
Audio capture is more sophisticated, as everything depends on system settings and the desired effect of capturing. On my very typical system, I have two recording devices “Microphone (Realtek Audio)” and “Stereo Mix (Realtek Audio)”. To obtain the list of available and enabled devices, use
ffmpeg -list_devices true -f dshow -i dummy
The use of a microphone is obvious, and “Stereo Mix” can be used to capture sounds produced by software.
The required device should be enabled in system settings: legacy control panel => Sound => (“Change sound card settings” => Recording) or (“Manage Audio Devices”).
Synchronization between Audio and Video
It was the first problem I noticed: the delay between video and audio. The parameter
itsoffset solves this problem. In the command line sample shown above, it fixes the delay of audio relative to video by delaying video.
If this parameter is placed in the audio line, it will delay audio relative to video.
set microphone="Microphone (Realtek Audio)"
set mix="Stereo Mix (Realtek Audio)"
if "%outputFile%"=="" set /p outputFile=Output file name:
if "%outputFile%"=="" goto:request-file
-f dshow -i audio=%audioChoice% ^
-f gdigrab -itsoffset %videodelay% -i desktop -c:v libx264rgb ^
-framerate %framerate% -crf %quality% -preset ultrafast ^
The file name is requested by the script or entered as a command-line parameter, other parameters are rarely changed, can be adjusted manually.
The user will need to edit the path to “ffmpeg.exe” or setup the
PATH environment variable accordingly.