VideoWriter - Change Framerate After Open

Some formats (in particular, mp4) default to saving stream metadata at the end of the stream. Given this, it seems like if I’m writing to mp4 format, I should be able to tell the VideoWriter what the framerate is at any point before the stream ends. Is this possible? The backend is FFMPEG, so this might be a question for FFMPEG instead of OpenCV.

The reason I ask is that I am using OpenCV to record an MJPEG stream from a network source (http) to an MP4 file. For whatever reason, regardless of the actual stream framerate, the VideoCapture object thinks the incoming rate is 25 FPS. I might set the camera source to 10 FPS, which then results in a video that plays back at 2.5x speed. I think the VideoCapture is just using some default value, since MJPEG doesn’t have any framerate information.

I control both ends of this system, so I could create a way for my recording device to ask the streaming device what its framerate is, but it seemed more elegant to measure the average framerate and write that into the MP4. Is that not possible?

Python 3.9.12 with opencv_python

you should not use opencv for that.

you should use ffmpeg or gstreamer, or whatever other media APIs are available to you.

“frame rate” is an illusion.

every video frame comes with timestamp. usually they’re equally spaced. not always.

when you read a frame, it comes with that timestamp. you write the same timestamp to your output.

actually, if all you’re doing is moving video, DO NOT decode it at all. keep the encoded stream. just move that around.

all of that is not among the use cases of OpenCV. OpenCV is for computer vision, not for handling media.

In my own defense, this is all code I inherited and nothing would make me happier than to throw it all away! You’ve made a good case for doing exactly that. I’ll find a way of doing what I want in C++ and use libffmpeg directly. Thank you for your input!

1 Like

I’d recommend that you look at PyAV. it’s got a couple examples. it supposedly works like regular ffmpeg APIs.

there may be other “proper” wrappers for python but that’s the one I trust because it doesn’t attempt to dumb it down too much or add too much flourish. many other wrappers push data through pipes into an ffmpeg subprocess.

there is one little problem with PyAV, or not, depending on your needs: the “owner” of that project refuses to let anyone implement hardware acceleration. it might get forked, or one of the deep learning frameworks will do their own thing (they need fast video I/O and are looking around).