Can't save a video in opencv

Question:

I am trying to save my video using opencv write method but the video is saved with 0 kb. what’s wrong in my code.

import cv2

cap = cv2.VideoCapture("k1.mp4")
# assert cap.isOpened()
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
fourcc = cv2.VideoWriter_fourcc(*'MP42')
out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (640,480))
# assert out.isOpened()

while cap.isOpened():
    ret, frame = cap.read()
    # if not ret: break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    fgmask = fgbg.apply(gray)
    thresh = 2
    maxValue = 255
    ret, th1 = cv2.threshold(fgmask, thresh, maxValue, cv2.THRESH_BINARY)

    color_space = cv2.applyColorMap(th1, cv2.COLORMAP_JET)
    result_vid = cv2.addWeighted(frame, 0.7, color_space, 0.7, 0)

    out.write(result_vid)

    cv2.imshow("vid", result_vid)
    if cv2.waitKey(20) == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()
Asked By: captainsameer

||

Answers:

import cv2
cap = cv2.VideoCapture(0)
# assert cap.isOpened()

# Automatically grab width and height from video feed
# (returns float which we need to convert to integer for later on!)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# MACOS AND LINUX: *'XVID' (MacOS users may want to try VIDX as well just in case)
# WINDOWS *'VIDX'
writer = cv2.VideoWriter('local_capture.mp4', cv2.VideoWriter_fourcc(*'VIDX'),25, (width, height))
# assert writer.isOpened()

# This loop keeps recording until you hit Q or escape the window
# You may want to instead use some sort of timer, like from time import sleep and then just record for 5 seconds.
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    # if not ret: break

    # Write the video
    writer.write(frame)

    # Display the resulting frame
    cv2.imshow('frame',frame)

    # This command let's us quit with the "q" button on a keyboard.
    # Simply pressing X on the window won't work!
    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
writer.release()
cv2.destroyAllWindows()
Answered By: Sarthak Dandriyal

The problem is that the video codec and the video container format do not match.

When executing your code, I am getting an error message (in the console windows):

OpenCV: FFMPEG: tag 0x3234504d/’MP42′ is not supported with codec id 15 and format ‘mp4 / MP4 (MPEG-4 Part 14)’
[mp4 @ 00000155e95dcec0] Could not find tag for codec msmpeg4v2 in stream #0, codec not currently supported in container

  • You are using fourcc = cv2.VideoWriter_fourcc(*'MP42'), and M420 applies video codec MPEG-4v2.
  • Video output file name is 'output.mp4'.
    The .mp4 extension applies MP4 container format.

Apparently .mp4 video file cannot contain video encoded with MPEG-4v2 codec.

You may either change codec, or change file format.

Example:

  • Changing output file name to 'output.avi' or 'output.wmv' works.
  • Changing the codec to MPEG-4: fourcc = cv2.VideoWriter_fourcc(*'mp4v') (and keeping file name 'output.mp4') also works.

One more issue:

Add the following code after ret, frame = cap.read():

if not ret:
    break;
Answered By: Rotem

Although your solution was to match the video codec and the video container format correctly, I wanted to add that another common reason the output file size is 0 kb when writing videos with OpenCV is a discrepancy between the captured video frame size and the output video frame size. This can be solved by replacing the hard coded output frame size with one calculated from the input video.

cap = cv2.VideoCapture('input.mp4')

w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frameSize = (w, h)
fps = 20
fourCC = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourCC, fps, frameSize)

while True:
    ret, frame = cap.read()
    ...
    result_vid = ...
    ...
    out.write(result_vid)
    ...

cap.release()
out.release()
cv2.destroyAllWindows()
Answered By: Callum
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.