Prasad
Prasad

Reputation: 1215

cv2.VideoWriter in RPi3 is faster than actual

I am trying to record the Logitech Webcam video. The cam is able to record it but 40 sec video is recorded for only 6 seconds with some nX speed. I referred the following link for the solution but it couldn't solves the problem in RPi. The important thing is the code works find in Ubuntu desktop but may be RPi is slower to process.

Here is my code snippet:

fourcc = cv2.cv.CV_FOURCC(*'XVID')
videoOut = cv2.VideoWriter("video_clip.avi", fourcc, 20.0, (640, 480))
start_time = time.time()
frame_count = 0
while True:
    ret, frame = cap.read()
    videoOut.write(frame)  # write each frame to make video clip
    frame_count += 1

    print int(time.time()-start_time)  # print the seconds
    if int(time.time()-start_time) == 10:
        videoOut.release()
        break
        # get out of loop after 10 sec video
print 'frame count =', frame_count 
# gives me 84 but expected is 20.0 * 10 = 200

Upvotes: 2

Views: 2253

Answers (2)

zindarod
zindarod

Reputation: 6468

Making a list of frames might not work if you run out of memory. The alternative can be to calculate the fps dynamically and then remux the video with the new fps using ffmpeg.

import numpy as np
from skvideo import io
import cv2, sys
import time
import os

if __name__ == '__main__':

    file_name = 'video_clip.avi'

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    videoOut = cv2.VideoWriter(file_name, fourcc, 30.0, (640, 480))
    cap = cv2.VideoCapture(0)

    if not cap.isOpened() or not videoOut.isOpened():
        exit(-1)

    start_time = time.time()
    frame_count = 0
    duration = 0
    while True:
        ret, frame = cap.read()
        if not ret:
            print('empty frame')
            break
        videoOut.write(frame)  # write each frame to make video clip
        frame_count += 1

        duration = time.time()-start_time
        if int(duration) == 10:
            videoOut.release()
            cap.release()
            break

    actualFps = np.ceil(frame_count/duration)

    os.system('ffmpeg -y -i {} -c copy -f h264 tmp.h264'.format(file_name))
    os.system('ffmpeg -y -r {} -i tmp.h264 -c copy {}'.format(actualFps,file_name))

Upvotes: 3

Meet Taraviya
Meet Taraviya

Reputation: 889

I had the same question some time ago. I did a lot of searching, but did not find a solution. The problem is the fps passed is the rate at which the video will be played. It does not mean that the video will be recorded at that FPS. AFAIK, there is no direct way to set the recorded FPS. If your recorded FPS had been too high, you could downsample (ie keep only 1 frame for each time period). But from what you describe, it seems that it is much lower than required. This is a hardware limitation and nothing can be done about it.

With respect to setting the recorded FPS, I found a workaround. I create the videoWriter after capturing all the frames in a list. In this way, I can calculate the recorded FPS and pass it to VideoWriter when creating it.

Upvotes: 5

Related Questions