Search code examples
pythonopencvvideo-capture

cv2.VideoWriter will not write file using fourcc h.264 (with logitech c920, python 2.7, windows 8)


I am new to python (2.7) and opencv (3.0) (and video streaming/writing in general) so forgive this.

I am using the logitech c920 as my webcam and it can stream video compressed in h264 format so I am trying to write a simple app that sets 4 properties of the VideoCapture instance (fourcc to h264; width to 1920; height to 1080; and fps to 30), and then records a video to the directory one level up named test.mp4 and shows the recording on my screen. Here is code:

import sys
import cv2 as cv

cap = cv.VideoCapture(0)
fourcc = cv.VideoWriter_fourcc('H','2','6','4')                     

cap.set(6, fourcc)
cap.set(3,1920)
cap.set(4,1080)
cap.set(5, 30)                                  

vid = cv.VideoWriter('../test.mp4', fourcc, 20.0, (640,480))     
print vid.isOpened() #returns false :(                                                       
while (cap.isOpened()):                                     

  ret, frame = cap.read()                                  

  if (ret == True):                                        

   #gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)          


   vid.write(frame)

   cv.imshow('window', frame)                           

   if (cv.waitKey(1) & 0xFF == ord('q')):                  
    break

cap.release()
vid.release()                                              
cv.destroyWindow('window')     

cv.imshow('window',frame) works just fine, and the properties are all set; however, vid.isOpened() return false so clearly I have done something wrong in the above. If I pass -1 for the fourcc, I am allowed to pick from a list of codecs and i420 is available and says (for logitech cameras) and vid.isOpened() returns true if I change the file extension from mp4 to avi (I guess that means i420 cannot be stored as .avi ?), however, test.avi is always huge and seemingly raw, 100MB for a few second test video and will not open.

Any help with this would be great, thanks a lot


Solution

    • Keep in mind that OpenCV automatically decompresses the incoming H264 stream from the webcam. You cannot pass on the compressed stream. You must recompress.
    • Since the codec ID of -1 displays a prompt asking you for chosing a codec, I assume you are on Windows. On Windows, OpenCV uses ffmpeg or "Video for Windows" backends. Unfortunately, it seems you cannot tell when OpenCV uses which backend. The dialog asking to select an encoder looks like the VfW dialog. There are no sane h264 VfW encoders, you probably did not install a hackish one like x264vfw, so you cannot choose h264 here.
    • The AVI container does not support b-Frames. H264 uses b-frames by default. You cannot change these encoder settings from within OpenCV. As a result, you should not choose AVI for H264 encoded video.
    • In order to save to another container, ffmpeg should be used. I can only guess OpenCV cooses backends wisely and based on container. You should be able to encode h264 into MKV or MP4. Bear in mind that there is some kind of "FOURCC to ffmpeg-Encoder-ID" translation takes place.