Reputation: 1215
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
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
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