Opencv offers method to read video from camera, file or any video stream and write it to a file. We can get video frame by frame and process and save it to output file. In this tutorial we will read video from camera or file and apply some operations on it and then write to a new video file.

Read Video

To read a video file, we can use VideoCapture method. It can be used with cameras connected to system, video files or network stream. First we read and get its details.

import cv2

# read video from file
cap = cv2.VideoCapture('VIDEO_PATH')

# read from webcam
cap = cv2.VideoCapture(0) # 0 for default cam

# read from network
cap = cv2.VideoCapture('IP_HERE')

Now before getting video frames, we can get some metadata about video like fps, frame width and height, total frames etc.

video_fps = cap.get(cv2.CAP_PROP_FPS),
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)

print(f"Frame Per second: {video_fps } \nTotal Frames: {total_frames} \n Height: {height} \nWidth: {width})

We can read a frame using cap.read method, which returns frame and status for next frame which if false is end of video.

ret, frame = cap.read()
# show frame
cv2.imshow(frame)
cv2.waitKey(0)
cv2.destroyAllWindows()

Now to get all the frames in video, we can create a while loop to run until the end of video.

while True:
    ret, frame = cap.read()
    if not ret: break # break if no next frame
    
    cv2.imshow(frame) # show frame
    
    if cv2.waitKey(1) & 0xFF == ord('q'): # on press of q break
        break
        
# release and destroy windows
cap.release()
cv2.destroyAllWindows()

We can apply different operations on video and then can show to using opencv or can write frame to directory or create a new video file.

Write Video

For writing a video, cv2 offers VideoWriter method to write to a file. We can write processed frames with different configurations. Video writer requires frames per second, width and height of a new video file which if we want same as original, we can get from above method and pass to this function.

fourcc = cv2.VideoWriter_fourcc(*'X264')
writer = cv2.VideoWriter('OUTPUT_PATH', fourcc,
                     video_fps, (int(width), int(height)))

We will use above code to read video file and for each frame we convert it to grayscale and write back to video using writer.write method. So complete code will be as follows.

import cv2


cap = cv2.VideoCapture("VIDEO_PATH")


# Get video metadata
video_fps = cap.get(cv2.CAP_PROP_FPS),
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)

# we are using x264 codec for mp4
fourcc = cv2.VideoWriter_fourcc(*'X264')
writer = cv2.VideoWriter('OUTPUT_PATH.mp4', apiPreference=0, fourcc=fourcc,
                     fps=video_fps[0], frameSize=(int(width), int(height)))

while True:
    ret, frame = cap.read()
    if not ret: break # break if cannot receive frame
    # convert to grayscale
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    writer.write(frame) # write frame
    
    if cv2.waitKey(1) & 0xFF == ord('q'): # on press of q break
        break
        
# release and destroy windows
writer.release()
cap.release()
cv2.destroyAllWindows()

For more details about video operation in opencv, visit official documentation.

https://docs.opencv.org/3.4/dd/d43/tutorial_py_video_display.html