🌐
OpenCV Q&A Forum
answers.opencv.org › question › 221029 › videowriter-recorded-video-play-too-fast
VideoWriter: recorded video play too fast - OpenCV Q&A Forum
November 4, 2019 - This means you are probably missing frames and so your written video looks like it is running very fast. You can tell be adding a simple counter for the number of frames. Then opening the written video to see how many frames are included. BTW, imshow takes time too.
Discussions

OpenCV frame writing too slow
I’m trying to save a video with OpenCV with this code import cv2 cap = cv2.VideoCapture('v4l2src device=/dev/video0 io-mode=2 ! image/jpeg, width=(int)1920, height=(int)1080, framerate=30/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw, format=BGR ... More on forums.developer.nvidia.com
🌐 forums.developer.nvidia.com
1
0
January 9, 2021
OpenCV writing video at 2x speed at 60 fps and writing correct speed at 30 fps
fps means frames per second. If you write 60 frames, and you make the video play at 30 fps, it will take 2 seconds to go over all 60 frames. If you make the video 60fps, using the same 60 frames, it will now take 1 second instead of 2, because 60 fps will play 60 frames per second. So if you write the same amount of frames, and play at different fps speeds, you will get different length videos... More on reddit.com
🌐 r/learnpython
11
1
January 14, 2021
VideoWriter.write() very slow - Python - OpenCV
Hi, I’m using opencv in python on ubuntu to record a couple of IP cameras and save the video in a file but the issue I’m encountering is that the write method is very slow for 1080p 25fps, it can barely handle about 12 fps while looking at a white wall and if I film something with more ... More on forum.opencv.org
🌐 forum.opencv.org
0
November 2, 2022
cv::VideoWriter does not support recording with variable frame rate
System Information OpenCV 4.7.0 Arch Linux gcc version 12.2.1 20230201 Detailed description FFMPEG backend of cv::VideoWriter class uses incorrect algorithm to compute pts of output frames. In CvVi... More on github.com
🌐 github.com
4
March 24, 2023
🌐
Intel Community
community.intel.com › t5 › Intel-Distribution-of-OpenVINO › Improve-speed-of-OpenCV-VideoWriter-async-video-read-and-write › td-p › 1309005
Improve speed of OpenCV VideoWriter (async video read and write) - Intel Community
September 9, 2021 - I am processing a pre-recorded video at 30fps and saving the results into a video with cv2.VideoWriter. I noticed that the video writing operation seems to be too slow to run smoothly at 30fps, in the sense that some frames in the input video are skipped and not read.
🌐
OpenCV Q&A Forum
answers.opencv.org › question › 132122 › opencv-videowriter-video-output-is-much-faster-than-normal-time
OpenCV VideoWriter() video output is much faster than normal time. [closed] - OpenCV Q&A Forum
videowriter · asked 2017-03-08 10:33:18 -0600 · iPikachu 1 ●1 ●2 · Hi everyone, I have a issue with my video capture code where the output of the video is super fast when outputted, I searched some documents and they all suggest that the problem is due to the fps of the camera not in sync to the output video fps, therefore making the output video faster or slower than normal time (capture fps > write fps: slower, capture fps < write fps: faster).
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › robotics & edge computing › jetson systems › jetson nano
OpenCV frame writing too slow - Jetson Nano - NVIDIA Developer Forums
January 9, 2021 - I’m trying to save a video with OpenCV with this code import cv2 cap = cv2.VideoCapture('v4l2src device=/dev/video0 io-mode=2 ! image/jpeg, width=(int)1920, height=(int)1080, framerate=30/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink', cv2.CAP_GSTREAMER) file_name = "abc.avi" fourcc = cv2.VideoWriter_fourcc(*'MPEG') width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) fps = cap.get(cv2.CAP_...
🌐
Reddit
reddit.com › r/learnpython › opencv writing video at 2x speed at 60 fps and writing correct speed at 30 fps
r/learnpython on Reddit: OpenCV writing video at 2x speed at 60 fps and writing correct speed at 30 fps
January 14, 2021 -

So, I was basically creating a script when gets the screenshots into numpy array inside while loop and adds those to cv.VideoWriter() this is kind of weird that when I set the fps to 60 it gave 2x speed in the resultant video and when it was 120 fps it gave 4x speed but it have correct speed at 30 fps. Did anyone understand why this might be happening ? my monitor has 59 Hz refresh rate btw pretty basic dell monitor.

🌐
OpenCV
forum.opencv.org › python
VideoWriter.write() very slow - Python - OpenCV
November 2, 2022 - Hi, I’m using opencv in python on ubuntu to record a couple of IP cameras and save the video in a file but the issue I’m encountering is that the write method is very slow for 1080p 25fps, it can barely handle about 12 fps while looking at a white wall and if I film something with more movement it takes up to 0.15s for a single frame.
🌐
GitHub
github.com › opencv › opencv › issues › 23403
cv::VideoWriter does not support recording with variable frame rate · Issue #23403 · opencv/opencv
March 24, 2023 - Here I see hw_frame->pts = frame_idx (or picture->pts = frame_idx) and then frame_idx++. This only works for sources with constant fps so that output frames will always have constant delta no matter how fast input device produces them. My USB webcam produces frames with variable fps (it decreases fps in order to increase exposure time when insufficient lighting), but cv::VideoWriter doesn't know this because cv::VideoCapture erase information about original pts values. Because of this, the generated file plays too fast.
Author: opencv
Top answer
1 of 1
11

-------- old - look up answer on bottom --------

Thank @Micka for the many advises, I found the right thing on the way.

Using cudacodec::VideoWriter is not that easy, after compiling I was not able to use it because of this error, and even if I can make it run, the deployment PC does not have a nvidia GPU.

Since I am going to use PCs with AMD CPUs as well, I can't use the cv::CAP_INTEL_MFX for the api-reference parameter of the cv::VideoWriter. But there is also the cv::CAP_OPENCV_MJPEG, which works fine for the MJPG codec (not all video container are supported, I use .avi, sadly .mkv was not working with this configuration). If the user does not use MJPG as a codec I use cv::CAP_ANY, and opencv decides what is to use.

So,

cv::VideoWriter videoWriter(path, cv::CAP_OPENCV_MJPEG, fourcc, fps, *size);

works pretty well, even on my old system.

Unfortunately I never changed the api-reference parameter before, only from ffmpeg to gstreamer, I read in the doc of opencv only the last line "cv::CAP_FFMPEG or cv::CAP_GSTREAMER." and I did not see that there is an "e.g." before... Thank you @Micka to make me read again.

P.S. for my performance problem with cv::imshow I changed from

cv::namedWindow(WINDOW_NAME, cv::WINDOW_NORMAL);

to

cv::namedWindow(WINDOW_NAME, cv::WINDOW_OPENGL);

Which obviously uses OpenGL, and does a better job. Also changing from cv::Mat to cv::UMat can speed up the performance, see here

-------------- EDIT better solution ----------------

Since I still had problems with the OpenCV VideoWriter for some systems, I was looking for another solution. Now I write the frames with FFMPEG. For FFMPEG I can use the GPU or CPU depending on the codec I use. If FFMPEG is installed via snapd (Ubuntu 18.04) it comes with cuda enabled by default:

sudo snap install ffmpeg --devmode

(--devmode is optional, but I had problems writing files on specific location, this was the only way for me to fix it)

And here is my code:

//this string is automatically created in my program, depending on user input and the parameters of the input frames

string ffmpegCommand = "ffmpeg -y -f rawvideo -vcodec rawvideo -framerate 50 -pix_fmt bgr24 -s 1920x1080 -i - -c:v h264_nvenc -crf 14 -maxrate:v 10M -r 50 myVideoFile.mkv";

FILE *pipeout = popen(ffmpegCommand.data(), "w");

int id = metaDataWriter.insertNow(path);

//loop will be stopped from another thread
while (this->isRunning) {
    //this->frames is a stack with cv::Mat elements in the right order
    //it is filled by another thread
    while (!this->frames.empty()) {


        cv::Mat mat = frames.front();
        frames.pop();
        fwrite(mat.data, 1, s, pipeout);

    }  
}

fflush(pipeout);
pclose(pipeout);

So a file (pipeout) is used to write the mat.data to ffmpeg, ffmpeg itself is doing the encoding and file writing. To the parameters:

-y = Overwrite output files without asking

-f = format, in this case used for input rawvideo

-vcodec = codec for input which is rawvideo as well, because the used cv::Mat.data has no compression/codec

-framerate = the input framerate I receive from my grabber card/OpenCv

-pix_fmt = the format of my raw data, in this case bgr24, so 8 bit each channel, because I use a regular OpenCV bgr cv::Mat

-s = size of each frame, in my case 1920x1080

-i = input, in this case we read from the stdinput you can see it here "-", so the file (pipeout) is captured by ffmpeg

-c:v = output codec, so this is to encode the video, here h264_nvenc is used, which is a GPU codec

-r = frame output rate, also 50 in this case myVideoFile.mkv = this is just the name of the file which is produced by ffmpeg, you can change this file and path

Additional parameters for higher quality: -crf 14 -maxrate:v 10M

This works very good for me and uses my hardware acceleration of the GPU or with another codec in charge the CPU. I hope this helps other developers as well.

Find elsewhere
Top answer
1 of 1
4

You're ignoring two important factors in your code:

Frame count in the while loop:

You want to write 10 seconds of video at 20 frames per second (fps). This gives you a total of 200 frames for the whole video. For this to happen, you'd need to be conscious of the waiting time inside the while loop before each frame is captured and written to file. If you ignore the waiting period, then:

  frameCount = 0
  while( int(time.time() - start_time) < capture_duration ):
      # we assume that all the operations inside the loop take 0 seconds to accomplish.

      frameCount = frameCount+1

  print('Total frames: ',frameCount)

In the above example, you'll notice that by ignoring waiting time, you'd be writing thousands of frames to video file in 10 seconds. Now 10 seconds of frames at 20 fps would give you 200 frames, to achieve this number of frames you'd need 50 milliseconds of waiting period before each frame is written to the file.

  frameCount = 0
  while( int(time.time() - start_time) < capture_duration ):
      # wait 50 milliseconds before each frame is written.
      cv2.waitKey(50)

      frameCount = frameCount+1

  print('Total frames: ',frameCount)

The total number of frames would be about 200 in the above example.

VideoCapture::read() is a blocking I/O call:

The cap.read() function performs two operations, namely VideoCapture::grab() and VideoCapture::retrieve(). This function waits for next frame to be grabbed, then decodes and returns the image. The waiting period depends on your camera fps.

So for example if your camera fps is 6, then in 10 secs you'd have captured 60 frames. You've set 20 fps as your VideoWriter property; 60 frames played as 20 fps gives you about 3 seconds of video.

To see how many frames are captured by your camera in 10 seconds:

  frameCount = 0
  while( int(time.time() - start_time) < capture_duration ):
      # wait for camera to grab next frame
      ret, frame = cap.read()
      # count number of frames
      frameCount = frameCount+1

  print('Total frames: ',frameCount)
🌐
GitHub
github.com › dataplayer12 › video-writer
GitHub - dataplayer12/video-writer: Super fast video writer for opencv using ffmpeg and libav · GitHub
Super fast video writer for opencv using ffmpeg and libav (C++ and python) Opencv's cv::VideoWriter is a pain to use.
🌐
Stack Overflow
stackoverflow.com › questions › 71951516 › cv2-videowriter-recorded-file-had-incorrect-speed
python - cv2.VideoWriter recorded file had incorrect speed - Stack Overflow
E.g. if you set to 30 fps but the distance between frames you give to the writer is 100 ms then the video will be played too fast (you would have to set 10 fps instead). ... you aren't pacing your screenshotting at all. you can't know at what ...
🌐
OpenCV Q&A Forum
answers.opencv.org › question › 16522 › video-recording-is-too-fast
Video Recording is too fast - OpenCV Q&A Forum
July 10, 2013 - This is a probable mismatch between the fps of your cam and your output video (10). If you match the fps of VideoCapture and VideoWriter, the speed would be normal.
🌐
OpenCV Q&A Forum
answers.opencv.org › question › 182611 › slow-video-write
Slow video write - OpenCV Q&A Forum
January 16, 2018 - Hi, I have a very simple program where I iterate over a video frame by frame and draw a circle at a (x,y) coordinate and create a new video. For a 6 second video this takes anywhere from 8-12 seconds. Can some one suggest some way to speed up this process? Else, suggest if there are other libraries ...
🌐
GitHub
github.com › opencv › opencv-python › issues › 846
write video with opencv · Issue #846 · opencv/opencv-python
May 17, 2023 - write video with opencv #846 · Copy link · Assignees · Labels · question · martin0496 · opened · on May 17, 2023 · Issue body actions · Hello · I tried to write a video using a sequence of images using : out = cv2.VideoWriter('sequencemjpg.mp4',cv2.VideoWriter_fourcc('P','I','M','1'), 5 , frameSize) The video is saved correctly with 5 fps as I mentioned. The problem occurs when I try to load it back, It plays too fast.
Author: opencv
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › robotics & edge computing › jetson systems › jetson nano
How to speed up Video Recording with Python cv2.VideoWriter on Jetson Nano - Jetson Nano - NVIDIA Developer Forums
February 20, 2023 - I found that when the cv2.VideoWriter using write() the program becomes slow. How can I speed up the cv2.VideoWriter? Maybe use Gstreamer or GPU or nvidia-component can speed up the FPS.
🌐
Stack Overflow
stackoverflow.com › questions › 68068510 › opencv-videowriter-object-is-fast-in-some-parts-of-the-video
python - OpenCV VideoWriter object is fast in some parts of the video - Stack Overflow
June 21, 2021 - It will be much appreciated if you guys can provide a solution for this. Thanks in Advance. ... You should replace the 20 you passed into the VideoWriter as the FPS with the actual FPS of the video you are opening.
🌐
OpenCV Q&A Forum
answers.opencv.org › question › 231952 › my-saved-video-run-in-very-fast-for-higher-resolution
My saved video run in very fast for higher resolution? - OpenCV Q&A Forum
August 1, 2024 - I saved video with 640x480 resolution and played with windows media player successfully. But when I save video with 1280x720 using opencv-python, it plays in very fast. my code sample fourcc = cv2.VideoWriter_fourcc(*'XVID') outVid=cv2.VideoWriter('outputMovie.mp4', fourcc, 30.0, (640, 480)) while(vid.isOpened()): check, frame=vid.read() if check: #print(check) #print(frame.shape) outVid.write(frame) #cv2.namedWindow("Capture Video", cv2.WINDOW_NORMAL) cv2.imshow("Capture Video", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break outVid.release() vid.release() cv2.destroyAllWindows()