Skip to content
Advertisement

I am trying to save frames from a webcam via Python and ffmpeg, but the video becomes way to fast

I get a stream of cv2 images from my webcam and want to save it to a video file. After playing a bit with cv2.VideoWriter() it turned out that using ffmpeg would provide more options and – apparently, following a few threads here on SO – lead to better results. So I gave the VidGear Python library a try, and it seems to work fine.

There is one catch though: My webcam provides a variable framerate, most of the time between 10 and 30 FPS. When saving these frames the video file becomes way too fast, like watching in fast-forward. One real-time minute becomes only a few seconds in the video.

I tried to play with various combinations of the ffmpeg’s -framerate and/or -r parameters, but without luck. Here is the command I am using right now:

ffmpeg -y -f rawvideo -vcodec rawvideo -s 1920x1080 -pix_fmt bgra -framerate 25.0 -i - -vcodec libx265 -crf 25 -r 25 -preset fast <output_video_file>

For the records, I am creating the WriteGear class from the VidGear library like this:

video_params = {
    "-vcodec": "libx265",
    "-crf": 25,
    "-input_framerate": 25,
    "-r": 25,
}
WriteGear(output_filename=video_file, logging=True, **video_params)

Any ideas what I am doing wrong here and how I need to call ffmpeg?

Advertisement

Answer

Ok, I solved my issue now by using cv2.VideoWriter() instead of the VidGear library. Don’t know why, but I was not able to get the latter working in a proper way – either it was me not using it correctly, or the library is broken (for my use case).

Either way, after playing around with the OpenCV solution, it turned out that using the VideoWriter class and providing the FPS value from the web cam everything works quite well now.

For the records, one thing to note though: Even after finding a correct codec for my platform and double-checking the dimensions of the images to be saved, I still ended up with an “empty” (1k) .mp4 video file. The reason was that all frames from my webcam came with 4 channels, but the VideoWriter class apparently expects frames with 3 channels instead, silently dropping all other, “invalid” frames. With the following code I was able to convert my 4-channel images:

if len(image.shape) > 2 and image.shape[2] == 4:
    image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement