VideoWriter outputs corrupted video file
Here's some simple code to save frames into a video file. I recommend creating another thread for obtaining the frames since cv2.VideoCapture.read()
is blocking. This can be expensive and cause latency as the main thread has to wait until it has obtained a frame. By putting this operation into a separate thread that just focuses on grabbing frames and processing/saving the frames in the main thread, it dramatically improves performance due to I/O latency reduction. You also can experiment with other codecs but using MJPG should be safe since its built into OpenCV.
from threading import Thread
import cv2
class WebcamVideoWriter(object):
def __init__(self, src=0):
# Create a VideoCapture object
self.capture = cv2.VideoCapture(src)
# Default resolutions of the frame are obtained (system dependent)
self.frame_width = int(self.capture.get(3))
self.frame_height = int(self.capture.get(4))
# Set up codec and output video settings
self.codec = cv2.VideoWriter_fourcc('M','J','P','G')
self.output_video = cv2.VideoWriter('output.avi', self.codec, 30, (self.frame_width, self.frame_height))
# Start the thread to read frames from the video stream
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
def update(self):
# Read the next frame from the stream in a different thread
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
def show_frame(self):
# Display frames in main program
if self.status:
cv2.imshow('frame', self.frame)
# Press Q on keyboard to stop recording
key = cv2.waitKey(1)
if key == ord('q'):
self.capture.release()
self.output_video.release()
cv2.destroyAllWindows()
exit(1)
def save_frame(self):
# Save obtained frame into video output file
self.output_video.write(self.frame)
if __name__ == '__main__':
webcam_videowriter = WebcamVideoWriter()
while True:
try:
webcam_videowriter.show_frame()
webcam_videowriter.save_frame()
except AttributeError:
pass
The output file is corrupted because of the wrong frame rate and frame resolution. Using this code :
out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))
We set the fps/frame rate per second 20. Which was not correct. Also, the frame width and height was wrong. I solved by getting fps, width, height from the captured web_cam profile.
cap = cv2.VideoCapture(0) #web-cam capture
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
out = cv2.VideoWriter('output.avi', -1,fps, (int(width), int(height)))
I added codec
parameter
to function cv2.videowriter
.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
codec = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
out = cv2.VideoWriter('output.avi',codec,fps, (int(width),\
int (height)))
#out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q') :
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
I hope you may see what is different in my code and your code.
Mine works now. Using MJPG
codec for .avi
extention
the indention is a bit messed,please do forgive cause I am very first time user.
The video
file is no longer corrupt.
I got the info from: Link