Writing to video with OpenCV


Let me just start this blog post by saying that writing to video with OpenCV can be a huge pain in the ass.

My intention with this tutorial is to help you get started writing videos to file with OpenCV 3, provide (and explain) some boilerplate code, and detail how I got video writing to work on my own system.

However, if you are trying to write videos to file with OpenCV in your own applications, be prepared to:

  1. Do research on the video codecs installed on your system.
  2. Play around with various codec + file extensions until the video writes to disk successfully.
  3. Make sure you’re in a secluded place away from children — there will be a lot of swearing and cursing.

You see, while the functions used to create video files with OpenCV such as cv2.VideoWriter , cv2.VideoWriter_fourcc , and cv2.cv.FOURCC  are quite well documented, what isn’t nearly as documented is the combination of codec + file extension required to successfully write the video file.

It’s been a long time since I needed to create an application to write videos to file with OpenCV, so when I sat down to compose the code for this blog post, I was very surprised (and super frustrated) with how long it took me to put together the example.

In fact, I was only able to get the code working with OpenCV 3! The code detailed in this post is not compatible with OpenCV 2.4.X (although I have highlighted the code changes required to run on OpenCV 2.4 if you want to give it a try).

Note: If you need help installing OpenCV on your system, please consult this page for a list of installation instructions for various platforms. Also be sure to take a look at the Quickstart Bundle and Hardcopy Bundle of Practical Python and OpenCV which include a downloadable Ubuntu VirtualBox virtual machine with Open 3 pre-configured and pre-installed.

Anyway, in the remainder of this post, I’ll demonstrate how to write video to file using OpenCV. And hopefully you’ll be able to use this code in your own applications without tearing out too much hair (I’m already so bald, so I don’t have that problem).

Looking for the source code to this post?
Jump right to the downloads section.

Writing to video with OpenCV

The purpose of this tutorial is to learn how to write frames to video using OpenCV and Python. We’ll discuss how to:

  1. Access a video stream, using either a builtin/USB webcam or the Raspberry Pi camera module.
  2. Read frames from the stream.
  3. Construct a new frame that visualizes the original image, plus the Red, Green, and Blue channel components individually.
  4. Write our newly constructed frame out to video file using OpenCV.

The results will look similar to the screenshot below:

Figure 1: Writing to video file with Python and OpenCV.

Figure 1: Writing to video file with Python and OpenCV.

Here we can see the output video being played in QuickTime, with the original image in the top-left corner, the Red channel visualization in the top-right, the Blue channel in the bottom-left, and finally the Green channel in the bottom-right corner.

Again, the code for this post is meant to be ran with OpenCV 3 or 4, so make sure you have the right version installed on your system before executing the code.

Creating our OpenCV video writer

Let’s go ahead and get started writing to video with OpenCV.

Open up a new file, name it write_to_video.py , and insert the following code:

We start off on Lines 2-8 by importing our required Python packages. We’ll be using the (highly efficient and threaded) VideoStream  class which gives us unified access to both builtin/USB webcams along with the Raspberry Pi camera module. The VideoStream  class is implemented inside the imutils Python package. You can read more about the VideoStream  class, how it can access multiple camera inputs, and efficiently read frames in a threaded manner in this tutorial.

Also, if you do not already have imutils  installed on your system, you’ll want to do that now:

From there, we parse our command line arguments on Lines 11-20. Our write_to_video.py  script requires one command line argument, followed by three optional ones:

  • --output : This is the path to where our output video file will be stored on disk.
  • --picamera : Here we can specify if we want to use the Raspberry Pi camera module instead of a builtin/USB camera. Supply a value > 0 at runtime to access the Pi camera module.
  • --fps : This switch controls the desired FPS of the output video. Ideally, the FPS of the output video should be similar to the FPS of your video processing pipeline.
  • --codec : Here we supply the FourCC, or four character code, an identifier for the video codec, compression format, and color/pixel format in video files.

As I mentioned at the top of this post, you’ll likely be spending a lot of time tweaking the --output  video file extension (e.x., .avi , .mp4 , .mov , etc.) and the --codec  value.

As the name suggests, the FourCC is always four characters. Popular examples include MJPG , DIVX , and H264 . You can see the entire list of possible FourCC codes here.

When I originally wrote the code for this blog post, I spent hours trying to figure out the right combination of both file extension and FourCC. I tried dozens of combinations, but none of them worked.

Furthermore, these combinations are also a bit temperamental. When I tried using a MJPG  codec with a .mp4  or .mpg  file extension, the video wouldn’t write to file. But when I used MJPG  with a .avi  file extension, the frames were magically written to video file.

Baffling, right?

My point here is that you’ll need to spend time playing around with these values. Depending on your setup and video codecs installed on your system, different combinations may work while others may not.

That said, I found the combination of MJPG  and .avi  worked on both my OSX machine and my Raspberry Pi out of the box, so if you’re having issues getting video to write to file, be sure to try these combinations first!

Let’s continue working through the write_to_video.py  script:

Here we initialize our VideoStream  and allow the camera sensor to warmup (Lines 25 and 26).

We then initialize our fourcc  codec using the cv2.VideoWriter_fourcc  function and the --codec  value supplied as a command line argument.

Note: For OpenCV 2.4.X, you’ll need to change cv2.VideoWriter_fourcc(*args["codec"])  function to cv2.cv.FOURCC(*args["codec"]) .

From there, initialize a few more variables, including our video writer, width and height of our frame, and finally a NumPy array that will be comprised entirely of zeros (more on this later).

Now comes the main loop of our script:

On line 36 we start looping over frames from our video stream, reading them, and then resizing them to have a width of 300 pixels (Lines 39 and 40).

We then make a check to see if the writer  is None  (Line 43), and if it is, we need to initialize it. First, we grab the spatial dimensions (i.e., width and height) of the frame (Line 46) followed by instantiating the cv2.VideoWriter  (Lines 47 and 48).

The cv2.VideoWriter  requires five parameters:

  • The first parameter is the path to the output video file. In this case, we’ll supply the value of the --output  switch, which is the path to where our video file will live on disk.
  • Secondly, we need to supply the fourcc  codec.
  • The third argument to cv2.VideoWriter  is the desired FPS of the output video file.
  • We then have the width and height of output video. It’s important that you set these values correctly, otherwise OpenCV will throw an error if you try to write a frame to file that has different dimensions than the ones supplied to cv2.VideoWriter .
  • Finally, the last parameter controls whether or not we are writing color frames to file. A value of True  indicates that we are writing color frames. Supplying False  indicates we are not writing color frames.

You’ll notice that I am using a width and height that are double that of the original frame — why is that?

The reason is because our output video frame will have two rows and two columns — storing a total of four “images”. We thus need double spatial dimensions of the original frame.

Finally, Line 49 constructs an array of zeros with the same shape as the original frame.

We are now ready to construct or output frame and write it to file:

First, we split the frame into its Red, Green, and Blue components, respectively (Line 53). We then construct a representation of each channel using zeros  to fill in the appropriate dimensions (Lines 54-56).

We are now ready to create our output  video frame, where the dimensions will be exactly double the width and height of the resized frame (Line 62).

Lines 63-66 handle storing the original frame in the top-left corner of the output image, the Red channel in the top-right, the Green channel in the bottom-right, and finally the Blue frame in the bottom-left.

The output  frame is written to file using the write  method of the cv2.VideoWriter .

Finally, our last code block handles displaying the output frames to our screen and performing a bit of cleanup:

Be sure to make note of Line 84 where we call the release  method of the writer  — this ensures that the output video file pointer is released.

Running our OpenCV video writer

To execute our OpenCV video writer using a builtin/USB webcam, use the following command:

If you instead want to use the Raspberry Pi camera module, use this command:

In either case, your output should look similar to my screenshot below:

Figure 2: Reading frames from video stream, modifying them, and writing them to video file with OpenCV.

Figure 2: Reading frames from video stream, modifying them, and writing them to video file with OpenCV.

Here you can see the original frame on the left, followed by the modified output frame that visualizes the RGB channels individually on the right.

After pressing the q  key and terminating the Python script, we can see that example.avi  has been written to my disk:

Figure 3: After executing our Python script, a video has been successfully written to disk using OpenCV.

Figure 3: After executing our Python script, a video has been successfully written to disk using OpenCV.

I can then open up this file in QuickTime or VLC and view it:

Figure 4: Opening our video file.

Figure 4: Opening our video file.

A full video demonstration of the OpenCV video writer can be seen below:

Help! My video isn’t writing to file with OpenCV.

As I’ve mentioned multiple times earlier in this post, the main reason your video is not writing to file is likely the combination of video codec and file extension.

I found that by using a codec of MJPG  and file extension .avi , I was able to successfully write to video using OpenCV on both my OSX machine and Raspberry Pi. I would suggest starting with these values and working from there.

But in all honesty, you will have to spend time banging your head against a wall to resolve this problem. You’ll need to try different combinations of FourCC and file extensions. Furthermore, OpenCV does not return any helpful error messages regarding this problem, so it’s pretty much a trial and error situation.

While I haven’t attempted this myself, I have heard that installing FFMPEG (and even re-compiling OpenCV with FFMPEG support) can help enable more video codecs.

Finally, if you find a combination of FourCC and file extension that works, be sure to post in the comments section, including the:

  • FourCC that you used.
  • File extension.
  • Operating system.
  • And any other relevant information.

This way we can compile a set of combinations that routinely work and (hopefully) avoid the troublesome situation of frames not being written to video file.


In today’s blog post, we learned how to write frames to video using OpenCV and Python. Specifically, we used OpenCV 3 and the cv2.VideoWriter  method to handle writing frames to file.

The key to creating a working video writer is to determine the correct combination of (1) FourCC and (2) file extension.

Furthermore, you need to ensure you have the proper video codec installed on your system –otherwise, your frames will not be written to file (and OpenCV won’t provide you with any helpful error messages or warnings).

If you find a combination of FourCC and file extension that works for you, be sure to post in the comments section, detailing which FourCC you used, the video file extension that worked, your operating system, and other other relevant information on your setup. Ideally, we can create a list of FourCC and file extension combinations that routinely work for people.

In next week’s post, we’ll create a more practical application of video writing were we save key event video clips, allowing us to parse an entire video file and save only the most interesting clips.

Before you go, be sure to signup for the PyImageSearch Newsletter using the form below — you won’t want to miss the next post on key event video clips!


If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL! Sound good? If so, enter your email address and I’ll send you the code immediately!

, , , , , ,

96 Responses to Writing to video with OpenCV

  1. Jon February 22, 2016 at 11:48 am #

    Hey Adrian,

    Thanks for the post. Writing video in OpenCV is indeed a pain in the ass. I’ve been using the codec pack provided on the fourcc web-site you mentioned under the XVID codec. I can’t remember which particular pack I downloaded (might of been FFDShow) but any one under the XVID option should do. In order to use the XVID codex I have to set the fourCC variable to:

    fourCC = cv2.VideoWriter_fourcc(‘X’,’V’,’I’,’D’)

    Which results in a lot smaller size with some image degradation. I would love to find a high quality compression codec that works but I have yet to.

    Also, if you set the fourCC variable to -1 then it will prompt you with a dialog that shows you all of the codecs installed on your system. This helps to figure out what you’ve got installed so you can experiment. Another serious limitation of OpenCV’s video I/O capabilities is the ability to read in a video of a certain extension then intialize your Video Capture object with the appropriate codec so that you can then read the frames from that particular type of video extension. I have only been able to read video files with .avi extension in OpenCV.

    • Adrian Rosebrock February 22, 2016 at 4:18 pm #

      Hey Jon, thanks for the comment. I think the FourCC==-1 option was only for Windows? I didn’t think that worked on any other operating systems.

      • Arnie May 1, 2018 at 2:25 am #

        Hey Adrian, I tried to write the “frame”. The output file was created however there’s nothing in the file. When I write the “output” it works properly tho. What could be the problem?

        • Adrian Rosebrock May 1, 2018 at 1:19 pm #

          Hi Arnie — are you using the code download associated with this blog post? Have you tried opening the output video in the VLC media player?

        • Daniel Ferguson September 28, 2019 at 12:45 am #

          Did you change the height and width in the cv2.VideoWriter construction? I had the same thing because I forgot to change from (w * 2, h * 2) to (w, h).

      • Daniel Ferguson September 28, 2019 at 12:48 am #

        I’m using Thonny on RPi3 with 2019-04-08-raspbian-stretch, and it printed for me in the Shell pane.

  2. SteveW February 22, 2016 at 2:30 pm #

    I agree that this OpenCV video-writing is very frustrating, and should not be so difficult.

    I have gotten the following to save video files correctly:
    fourcc = cv2.VideoWriter_fourcc(*’mp4v’) with *.mp4 to work on both a Raspberry Pi 2 running Wheezy and an old Lenovo T61 running Ubuntu 15.10.

    I have spent hours randomly experimenting with OpenCV3 video writing, and have concluded that I do not understand the underlying dependencies. For example, I could not get *.mp4 to work on the Ubuntu 14 LTS, possibly due to missing codecs in ffmpeg, so I switched to Ubuntu 15.10 and video writng works.

    I have processed both a video stream from a Logitech C920 webcam and pre-recorded mp4’s showing H264, before writing to the video files.

    I wish I knew a straightforward method to test which codecs and extensions might work on a given Linux install.

    • Adrian Rosebrock February 22, 2016 at 4:16 pm #

      Thanks for sharing Steve, myself and the rest of the PyImageSearch community thanks you 🙂

      I also agree, I wish there was a straightforward method to test video extensions and codecs, but I don’t know of one. A really hack-y way to do it would be to loop over all possible codecs on the FourCC.org website along with common video file extensions and then determine if frames are being written to file.

      • Ryan April 29, 2016 at 9:37 pm #

        Hey Adrian, I think I got encoding of H.264 video to work on my pi following your openCV build tutorials. This is what I have in my conf.json file. My code is slightly different from your source.

        “four_cc”: “cv2.VideoWriter_fourcc(‘H’,’2′,’6′,’4′)”,
        “vid_out”: “output.mkv”,

        The .mkv extension is what is needed for me to encode high res, low size video.

        Also, thanks so much for this blog, it’s teaching me a ton of new stuff.

        • Adrian Rosebrock April 30, 2016 at 3:52 pm #

          Thanks for sharing! I’ll be sure to give this a try the next time I boot up my Pi.

        • Bill W May 2, 2016 at 4:30 pm #

          Thanks, Ryan. Works like a charm!

          I also needed to bump gpu_mem from 128 to 144 to get past some ENOSPC errors on my Pi3/Camera2 setup.

  3. David McDuffee February 22, 2016 at 2:50 pm #

    I haven’t made the jump to OpenCV 3 yet, but when I had a contract that called for reading and writing video, I ran into similar issues using OpenCV 2.

    My own solution was to use ffmpeg to split the video into individual frames, use OpenCV on each frame, and use ffmpeg to re-encode the video. I still have a full head of hair.

    • Adrian Rosebrock February 22, 2016 at 4:15 pm #

      Thanks for sharing David. I’ve heard of using this as a hack to piece everything together. It certainly requires a bunch of extra steps, but as long as it works in the end, that’s all that matters 🙂

  4. Esko February 24, 2016 at 6:51 am #

    Hi Adrian,

    Here are my test results in Windows 10. I recorded 640×480, 25 fps, 100 frames
    Below are the results in the following order:
    codec / file extension / file size / CodecID given by Mediainfo / Player that could open the file (WMP = Windows Media Player)

    – / avi / 112512 kB / I420 / WMP, VLC, Films&TV, MovieMaker
    MJPG / avi / 14115 kB / MJPG / VLC
    MJPG / mp4 / 5111 kB / 6C / VLC
    CVID / avi / 7459 kB / cvid / WMP, VLC, MovieMaker
    MSVC / avi / 83082 kB / CRAM / WMP, VLC
    X264 / avi / 187 kB / H264 / WMP, VLC, Films&TV, MovieMaker
    XVID / avi / 601 kB / XVID / WMP, VLC, MovieMaker
    XVID / mp4 / 587 kB / 20 / WMP, VLC, Films&TV, MovieMaker

    • Adrian Rosebrock February 24, 2016 at 4:33 pm #

      Thanks for sharing!

    • Chetan Chilhate January 23, 2017 at 5:07 am #

      You saved my lot of time

    • Laura April 9, 2017 at 8:04 pm #

      I am using windows 10 and openCV2 and the combination .avi and MSVC was able to open on windows media player! Thank you!

  5. Godbid February 29, 2016 at 3:14 am #

    It successfully worked on my RaspberryPi B+ with OpenCV3.
    Thank you ! It’s very interesting !

  6. Kirk H March 1, 2016 at 12:45 pm #

    This was extremely helpful Adrian

    So far on my OSX 10.10.1 I have the following combinations working
    *’mp4v’ -> .mp4
    *’MJPG’ -> .avi

    The challenge I am having is getting a smaller file format to work. I have an original video that is mp4, 14:09 long and 83.4 MB. The resulting file from the mp4v to mp4 is nearly 6 GB.

    I’ve tried X264 to .avi, H264 to .avi, X264 to .mp4, H264 to .mp4, XVID to .avi
    none of these combinations produce a readable file for either Quicktime or VLC.

    Any thoughts on combinations to try?


    • Adrian Rosebrock March 1, 2016 at 3:34 pm #

      Wow, 6GB is large. What is the resolution of the frames that you are writing to file?

      • Kirk H March 1, 2016 at 7:28 pm #

        I continued to experiment and am now using avc1

        It has dropped the size by 25%. But that is still huge.

        Here is how I define my output video
        fourcc = cv2.VideoWriter_fourcc(*’avc1′)
        cv2.VideoWriter(“output_video.mp4”,fourcc, 29.41, (1920, 1200),True)

        I was hoping a format like X264 would give me a dramatic decrease in size, but I can’t figure out how to get X264 and H264 to work on my Mac.

        • Cesar W May 16, 2019 at 4:52 pm #

          Appreciate your combination Kirk H,

          You combination has worked for me in Mac OS Mojave v10.14.4.
          Will explore further…

  7. Guowei March 4, 2016 at 2:37 am #

    Thank you for your help.

    I had FFMPEG compiled with OPENCV3. I was able to read files. But had trouble writing files after processing. Seems like imutils videostream did the trick for me.

    Many thanks =]

  8. Hilman May 24, 2016 at 7:21 am #

    Adrian, I just have to stop by and say how awesome you are! Your code works out of the box with my Mac! Really thank you for this.

    Keep up the good works helping others out!

  9. Klaus June 2, 2016 at 2:43 pm #

    I cannot find any codec which saves the sound also.


    This one NOT.

  10. Zac Diggum June 7, 2016 at 7:22 pm #

    Also working:

    Saving uncompressed greyscale video:
    fourcc: Y800 -> 8bit, VLC plays it, FFmpeg reencodes it
    YV12 (12bit) and YV16 (16bit) seem to encode with OpenCV but won’t be played with VLC nor reencoded with FFmpeg.
    Set isColor=False in the cv2.Videowriter() constructor.

    If anyone has to do more serious video transcoding with Python I can recommend FFmpeg together with ffmpy.

    Forgot to mention: video container is .avi

    • Adrian Rosebrock June 9, 2016 at 5:31 pm #

      Thanks for sharing Zac!

  11. Peter Rexer June 8, 2016 at 7:18 pm #

    Anyone else get a IndexError: deque index out of range on line 38 of keyclipwriter?

    I’m wondering what’s wrong in the code, or how the deque is initialized somehow wrong.

    Any suggestions?

    Ah, nevermind, I figured it out… at least one of the calls to put a frame into the buffer are needed before the .start method.

  12. Klaus July 4, 2016 at 8:15 pm #

    to write the video,
    it does`nt work on my Ubuntu, but it worked on my Raspberry Pi.
    But still one thing is true:
    OpenCv and FFMPEG have the most problems of all big software!

  13. James July 23, 2016 at 4:26 am #

    Thanks to Kirk’s comment I have OpenCV ver 2.4.13 and Python 2.7.5 working on Mac OSX10.9.5 with my Logitech webcam using ‘mp4v’ and filetype ‘.mp4’. The exact code is:

    fourcc = cv2.cv.CV_FOURCC(‘m’, ‘p’, ‘4’, ‘v’)
    out = cv2.VideoWriter(‘output.mp4’, fourcc, 7.3, (640,480))

    Using Quicktime to record a short clip and then checking the framerate I was able to find the (very slow) framerate that my webcam was putting out.

    • Steven May 20, 2017 at 2:05 am #

      Just wanted to let you know that almost a year later your comment ended my night of frustration with OpenCV. THANK YOU!

  14. Carlos Torres July 25, 2016 at 6:42 pm #

    I have been following your progress (and purchased your first books) since your first draft. I am very happy with the book and with what you have done.

    I have a question. and I cannot find any threads on a solution. I am using raspberry pi 3 B (mate 16.04) for continuous and multiple video clip recordings (say about hr videos over 24 hrs). I am using cv2 video writer and release (python 2.7) opencv 2.4.9 (from packages). I am running out of “ram”!. The problem seems to be the video writer. I release the video every time a clip is competed. (even tried deleting and re-initializing the variables). The problem is not there if I saw frames (imwrite) or if I simply stream (not a buffer full issue). I even put the video generation code into a function (instead of a script) and the problem (out of memory) is still there. The system monitor shows the memory is being swallowed and it’s never release (video). The memory (and I assume the video) is only released if I stop the code (esc or ctrl+c) or if the system kills it.

    In summary. The videos are generated…but the video writers are not released which eats up all the memory and kills the process.

    Do you know if this an opencv2.4.9 / python wrapper issue? Do you know any work arounds?

    Thank you in advance and keep up the amazing site!


    • Adrian Rosebrock July 27, 2016 at 2:28 pm #

      Thanks for being a long-time follow of the PyImageSearch blog, Carlos!

      As for the memory issue, that sounds like a memory leak of some kind. I personally haven’t ran into this issue before, but I would suggest posting it on the official OpenCV forums. Be sure to post your exact OpenCV and Python versions like you did here. If there is a known issue with the video writer and memory leakage, they’ll certainly be able to let you know.

      • Carlos Torres August 17, 2016 at 1:13 pm #

        Hi Adrian,

        Just a quick update for those that might run into the same “memory” stupid issue. The issue seems to be the codec, but it could just be the way the video writer is implemented! Other codecs in 2.4.9 use less memory, but the non-video release remains. I just installed 3.1.0 from srcs (contrib-modules has a small, but annoying hdf5 issue – found a work around), opencv3.1.0 has a new codec definition method (removed cv), which really makes me think the issue was opencv2.4.9. Conclusion, 3.1.0 from srcs works. The video writer definition changes (as you pointed, from 2.4.x to 3.x). RAM consumption is no longer a problem. The videowriter is actually being released and new-frame updates instead of “accumulates”.

        • Adrian Rosebrock August 18, 2016 at 9:31 am #

          Thanks for following up on this Carlos, I really appreciate it (as I’m sure other PyImageSearch readers do as well). I’ve made note of your comment and have included in my OpenCV notes that I refer to. I’ll absolutely keep this in mind the next time I’m using the VideoWriter. Thanks again!

  15. Wang, Teng-Hong August 31, 2016 at 2:48 pm #

    cam = cv2.VideoCapture(0) # 0: build-in, 1: external
    fourcc = cv2.VideoWriter_fourcc(‘M’,’J’,’P’,’G’)
    vid = cv2.VideoWriter(‘output.avi’, fourcc, 6, (640,480))

    After several try, I finally find this article.
    my enviroment set as below.
    OS: Windows 10 Home 64 bits
    PL: Python 2.7.12
    Lib: OpenCV 3.1
    Player: VLC Player
    MJPG&avi is very well combination.
    I had tried XVID&avi / MJPG/mpg all get some trouble.
    and M$ media player with Win7codecs can’t play the video.
    So I turn to VLC Player.

  16. Islam September 7, 2016 at 1:52 pm #

    Hi Adrian
    I use this code to record 2 minutes video to file as the table below:

    # fps CODEC ext. Duration actual duration@file Size (KB)
    1 20 MJPG .avi 2 minutes -48 s 57,320
    2 20 H264 .avi 2 minutes -43s 482
    3 20 X264 .avi 2 minutes -42s 482
    4 20 Mp4v .avi 2 minutes -41s 2,710

    I find clip duration is less than two minutes (120 seconds) while the camera was taking 2 minutes real-time in recording. Could you help me how can be satisfied that results?

    • Adrian Rosebrock September 8, 2016 at 1:22 pm #

      It sounds like there is a mismatch between the FPS of your output file and your recording. Tweak the FPS parameter to cv2.VideoWriter to approximate the FPS of your actual recording.

  17. kapyar September 9, 2016 at 6:16 pm #

    What about python27 + openCV2.4 for my mac it works with next configuration:

    fourcc = cv2.cv.CV_FOURCC(*”DIVX”)
    self.out = cv2.VideoWriter(‘output.avi’,fourcc, int(25), (640,480))

  18. rsc October 7, 2016 at 1:38 am #

    On my OSX 10.11.6 (El Captain), the following settings worked for rcording video:

    fps = 25
    capSize = (int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
    fourcc = cv2.cv.CV_FOURCC(‘m’, ‘p’, ‘4’, ‘v’) # note the lower case
    writer = cv2.VideoWriter()
    success = writer.open(‘output.mov’,fourcc,fps,capSize,True)

    • Adrian Rosebrock October 7, 2016 at 7:19 am #

      Thanks for sharing!

  19. Jim December 7, 2016 at 7:03 am #

    Hi Adrian, Wouldn’t it be simpler to use picamera to record video as in the code below? Or is it preferable to use OpenCV.

    with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)

    • Adrian Rosebrock December 7, 2016 at 9:36 am #

      You can certainly use the picamera video to write frames to file, that’s not an issue at all. The problem is that you cannot access and process these frames prior to them being written to file.

  20. David January 9, 2017 at 8:02 am #

    Hi Adrian,
    Since some weeks, I have a problem to a video in a file.
    I use exactly the same code than you, but when I read the file, I have only one frame to see. It’s as if the frames were not refreshed
    The size of the file is correct, no error on the shell …..
    Have you ever noticed an identical problem ?



    • Adrian Rosebrock January 9, 2017 at 9:05 am #

      Hey David — are you executing the code via a Python shell (i.e., IDLE) or via the command line? If you’re using IDLE the cv2.imshow call is likely hanging if there is not a cv2.waitKey(1) statement following it. For working with video files I recommend using the terminal and executing the actual script rather than utilizing IDLE.

      • David January 10, 2017 at 6:58 am #

        Hi Adrian,

        I have seen this problem in my original soft. In this soft, video recording is in a thread.
        So I decide to code a simply video recorder with no thread… But it is the same result, the video is just a loop of 1 frame.

        It’s weird, a few months ago, it worked perfectly.

        It is likely a raspicam driver update which is guilty or maybee the cam (I use the rapicam V2.1)….. I don’t know

        I tested your solution, with or without Python shell, just 1 frame on the video file again ….

  21. sinjon March 22, 2017 at 8:18 am #

    Hello Adrian,

    I seem to be getting a syntax error on the “None” in “if writer is None”

    I’ve tried using = and == instead of ‘is’ as well as when writer is declared but no luck.

    any ideas?

    Thanks in advance

    • Adrian Rosebrock March 22, 2017 at 8:40 am #

      Make sure you use the “Downloads” section of this tutorial to download the source code + project structure. It seems like you might have copied and pasted some code incorrectly.

      • sinjon March 22, 2017 at 10:45 am #

        Sweet thank you.

        One other error I’m getting in this code and some other is that break is outside loop. when I’ve replaced destroyAllWindows then I get an error on:
        (h, w) = image.shape [:2]
        NoneType object has no attribute ‘shape’

        • Adrian Rosebrock March 23, 2017 at 9:33 am #

          It sounds like you’re having issues reading your image/frames from disk or video stream. Please see this blog post on NoneType errors for common problems and resolutions to the issue.

  22. Sinjon March 23, 2017 at 10:09 am #

    Thank you, that sorted that problem1

    When I try run this code and other ones that use VideoStream I get the following error.

    Traceback (most recent call last):

    (h, w) = image.shape[:2]
    AttributeError: ‘NoneType’ object has no attribute ‘shape’

    I read your article on the causes of this error, I’ve tried simplifying this code to record a video to check I can read my image but no had no luck. My camera works and I’m able to take photos using raspistill and I’m able to load images. Thus I removed and re-installed opencv and numpy last night, but am still having the same problem. Have you got any advice how to resolve this?

    Many thanks Sinjon

    • Adrian Rosebrock March 25, 2017 at 9:37 am #

      If you’re still getting NoneType errors then OpenCV was likely compiled without video I/O support.

      • sinjon March 25, 2017 at 7:06 pm #

        Alright that makes sense.

        Would this of occurred during the installation / binding stage of opencv? I’ve removed and re-installed and yet it still persisted. I’ve also been trying to installing drivers, changing codec file formats, googling, searching through forums with no luck.

        is there a way to download specific video I / O packages?

        • Adrian Rosebrock March 28, 2017 at 1:10 pm #

          It would have occurred when you installed your video driver libraries + ran CMake to configure the build.

  23. Eeshwar G April 4, 2017 at 10:35 pm #

    Thanks a lot for this post!

    I ran the exact same code with the default codec(‘MJPG’) and output format(.avi) and it worked flawlessly.

    • Eeshwar G April 4, 2017 at 11:21 pm #

      I’m using Python 2.7 with OpenCV 3.2 on an Ubuntu 14.04 system.

      • Adrian Rosebrock April 5, 2017 at 11:50 am #

        Fantastic, I’m glad to hear it Eeshwar!

  24. Bietschhorn May 1, 2017 at 2:00 pm #

    Hello Adrian,

    Your tutorials are always perfect and I want to thank you for this.
    It has functioned immediately for me.
    But without any change except the usual upgrade update, I get:

    Traceback (most recent call last):
    File “WriteVideoRC.py”, line 40, in

    (h, w) = image.shape[:2]
    AttributeError: ‘NoneType’ object has no attribute ‘shape’

    I cannot get the reason because I am a newbie
    Any idea to help understand the problem ?

    Thank you in advance

    • Adrian Rosebrock May 3, 2017 at 6:04 pm #

      If you are getting NoneType errors I would suggest you first read this post on why the happen and how to resolve them.

      If you are new to OpenCV and image processing then I would highly suggest you work through Practical Python and OpenCV. You’ll quickly get up to speed and master the fundamentals. Be sure to take a look!

  25. sinjon price May 5, 2017 at 11:20 am #

    Hello Adrian,

    How would it be possible to put a mask in one of the boxes?
    I’m getting a type error long () argument must be a string or a number, not ‘builtin_function_or_method

    I’ve tried converting it to an int and float but then got a type error?

    Thank you in advance

    • Adrian Rosebrock May 8, 2017 at 12:36 pm #

      Hi Sinjon — can you elaborate more on what you mean by “put a mask in one of the boxes”? What exactly are you trying to accomplish?

  26. Rezig May 15, 2017 at 9:39 am #

    Hi Adrian

    I’am wondering if you have any idea about capturing video from blackmagic design intensity shuttle https://www.blackmagicdesign.com/fr/products/intensity is there any method like cv2.VideoCapture() to do that ?

    i’ll appreciate your help because i’am stucked in this part 🙁

    • Adrian Rosebrock May 17, 2017 at 10:09 am #

      Hi Rezig — Sorry, I do not have any experience with that piece of hardware.

  27. izzy May 24, 2017 at 12:45 am #

    Hi, first i would like to thank you for your tutorials. I have question, is there any way how to change resolution at videostream? I try “vs = VideoStream(usePiCamera=args[“picamera”] > 0, resolution=(1280,720)).start()” but it didn wotk. Resolution is still 640×480. Im using logitech c270. Thank you for your help!

    • Adrian Rosebrock May 25, 2017 at 4:22 am #

      It sounds like you need to modify the cv2.VideoCapture object directly. Setting the resolution in this manner can be quite buggy, but it might work in some cases as well. Take a look at the .set and .get methods of cv2.VideoCapture for more information.

      • izzy May 25, 2017 at 2:13 pm #

        Thanks, but it seems that it work properly only with resolution 640×480 🙂 Weird

  28. M0J0 May 29, 2017 at 5:10 pm #

    Hey dude! I have been working on a VideoWriter.write(frame) from a modified VideoCapture.read(vid) for the past 2 hours. Then I googled upon your blog, and tried your MJPG.avi combo and boom, it now works.

    Where is your donate button? The anguish you have helped alleviate has to worth a cup of coffee.

    Thank you kindly,



    • Adrian Rosebrock May 31, 2017 at 1:17 pm #

      Hi M0J0 — I don’t have a “donate button” per se, but if you would like to show your support of myself and the PyImageSearch blog, definitely consider picking up a copy of my book, Practical Python and OpenCV.

  29. Anthony The Koala June 12, 2017 at 1:33 am #

    Given that OpenCV is for the processing of video, is there another python module that handles audio such that you can multiplex the audio and video into one file and at the same time being mindful of ‘lip-sync’.
    Thank you,
    Anthony of Sydney Australia

    • Adrian Rosebrock June 13, 2017 at 11:05 am #

      Unfortunately, I do not have any experience working with audio libraries. I hope another PyImageSearch reader can jump in and help.

  30. Mirek Zvolsky July 19, 2017 at 9:26 am #

    I made tests with more codecs (see: fourcc.org), so I have now
    for extension in (‘avi’, ‘wmv’, ‘mpg’, ‘mov’, ‘mp4’, ‘mkv’, ‘3gp’, ‘webm’, ‘ogv’,):
    for codec in (‘3IVD’, ‘CJPG’, ‘DIV3’, ‘DIV4’, ‘DIVX’, ‘DX50’, ‘FFV1’, ‘H264’, ‘HFYU’, ‘IJLV’, ‘IYUV’, ‘MJPG’, ‘mp4v’, ‘MP42’, ‘MPEG’, ‘PIM1’, ‘THEO’, ‘V264’, ‘VP80’, ‘WMV1’, ‘WMV2’, ‘WMV3’, ‘X264’, ‘XVID’,):

    and I received following in players well running videos from opencv 3 compiled from sources:
    X264.3gp/C V264.3gp/C H264.3gp/C
    X264.mov/CF V264.mov/CF H264.mov/CF
    X264.mp4/CF V264.mp4/CF H264.mp4/CF
    X264.mkv/C V264.mkv/C H264.mkv/C
    X264.mpg V264.mpg H264.mpg
    X264.wmv V264.wmv H264.wmv
    VP80.ogv/C VP80.mov/C VP80.webm/C(from v3)F VP80.mkv/C VP80.wmv/C
    FFV1.mov FFV1.mkv
    X264.avi/C V264.avi/C H264.avi/C
    VP80.3gp/C FFV1.wmv VP80.avi/C FFV1.avi
    3IVD.mov DIV4.mov DIV3.mov WMV1.mov 3IVD.3gp WMV1.3gp WMV2.mkv
    3IVD.mkv DIV4.mkv DIV3.mkv WMV1.mkv WMV1.wmv WMV2.wmv 3IVD.wmv
    DIV4.wmv DIV3.wmv WMV2.avi 3IVD.avi DIV4.avi DIV3.avi WMV1.avi
    MP42.mov MP42.3gp MP42.mkv
    XVID.3gp/C mp4v.3gp/C DX50.3gp/C DIVX.3gp/C XVID.mov/C DIVX.mov/C
    mp4v.mov/C DX50.mov/C XVID.mp4/C mp4v.mp4/C DX50.mp4/C DIVX.mp4/C
    XVID.mkv/C mp4v.mkv/C DX50.mkv/C DIVX.mkv/C XVID.wmv/C mp4v.wmv/C
    DX50.wmv/C DIVX.wmv/C
    XVID.avi/C mp4v.avi/C DX50.avi/C DIVX.avi/C
    PIM1.mp4 PIM1.mkv PIM1.mpg PIM1.3gp MPEG.3gp PIM1.wmv MPEG.mp4
    MPEG.mkv MPEG.mpg PIM1.avi MPEG.wmv MPEG.avi MJPG.mov IJLV.mov
    CJPG.mov MJPG.mp4 IJLV.mp4 CJPG.mp4 MJPG.mkv IJLV.mkv CJPG.mkv
    MJPG.wmv MJPG.avi MJPG.3gp CJPG.3gp HFYU.mkv HFYU.avi HFYU.wmv
    IYUV.avi IYUV.wmv

    Especially interesting is THEO.ogv/CF (created by both opencv 2 (ie. python-opencv) and/or 3) which works in players and both Chrome+Firefox !

    • Adrian Rosebrock July 21, 2017 at 8:58 am #

      Wow, thank you for sharing the exhaustive set of tests Mirek! This is great.

  31. Ram July 29, 2017 at 9:12 pm #

    Hi Adrian,

    I have implemented this, but i do not get the FPS I want. I am trying to record at 30 fps but i get only 9 fps. I have no idea why. I put in a timer to execute the cleaning up code after 10 seconds and deleted the frames that are repeating.

    Also the program when run from a command prompt does not end(i.e does not give an prompt for the next command to be entered.).

    • Adrian Rosebrock August 1, 2017 at 9:46 am #

      Hi Ram — it’s hard to say what the exact issue is. Could be a problem with the frames being read from your camera sensor. It could also be the case that you’re pipeline is not reading at 30 FPS and is then only writing the frames back out at 9 FPS (although that seems odd).

  32. Ricardo August 15, 2017 at 3:12 pm #

    Hi Adrian, thanks for the very interesting post. Look, I’m planning to use a raspberry pi to record a long time period (>10 hours). Do you think is a good idea to use the raspberry for this? I’m planning to use a external disk. What would you recommend?
    Kind Regards,

    • Adrian Rosebrock August 17, 2017 at 9:16 am #

      I don’t see any reason off the top of my head why this wouldn’t work. Raspberry Pi’s are used in production systems.

  33. Nipuna October 9, 2017 at 5:06 am #

    Hi Adrien,

    Thank you for the wonderful post. I’ve create an app to stream 4 videos and record into one video output. I’ve used your post on using threads for different feeds also. Thank you for that too.

    While saving using videoWriter I had to to do lot of trial and error to find the correct fps for the output video. Is there a better way to find this ? Also if I am to use different brands of cameras, what should be my approach ?

    • Adrian Rosebrock October 9, 2017 at 12:14 pm #

      I’m not an expert with video writing and OpenCV, but in general I too have to use trial and error to determine the correct FPS for the output video.

  34. FreeSlave October 20, 2017 at 12:27 am #

    What is it with always writing to video FROM A CAMERA? Is that the only legal thing to do? I just want to write images from pixel buffers to M-JPEG. I guess it’s so trivial, no one talks about it.

    • Adrian Rosebrock October 22, 2017 at 8:47 am #

      You’re correct, it’s not exactly trivial. I’ve made note to cover this in a future blog post.

  35. jsplyy December 21, 2017 at 10:55 pm #

    In constructor function of VideoWriter, I set the fps is 10. But I call videoWriter.write(frame) function more than 10 times per second. So my question is what is the real fps in my saved video and which frames are saved?
    Input 100 fps when set fps as 10, what is the result? Will it save 10 fps? which 10 fps in input 100 fps will be saved?

    • Adrian Rosebrock December 22, 2017 at 6:39 am #

      If you set the FPS to 10 in the cv2.VideoWriter then the output video (should) playback at 10 FPS.

  36. amelia February 4, 2018 at 8:00 am #

    good morning please Im trying to use a part of your wonderfull code to save a video into a file but dont understand the meaning of –codec what i have to put in and fps ?

  37. Aaron February 11, 2018 at 2:12 am #

    Hi everyone,

    Im doing this with two webcams (USB) and after consistently after 30-40 minutes, they will crash on an exception i can’t seem to catch in python. Both webcams are usb webcam CMOS boards with 2.1mm lenses and are native in 640×480 60fps. I am running 640×480 at 15fps (dial it down).

    VIDIOC_DQBUF: No such device
    VIDIOC_DQBUF: No such device
    VIDIOC_DQBUF: No such device
    VIDIOC_DQBUF: No such device
    …… and it goes on

    I really don’t know what else to do… i’ve tried bumping the gpu and using codecs native to the camera board i.e. MJPG

    • Adrian Rosebrock February 12, 2018 at 6:28 pm #

      It looks like the crash is happening internally, maybe related to a system thread. I’m honestly not sure, I haven’t encountered this issue before. Have you tried posting on the official OpenCV forums as well? Sorry I couldn’t be of more help here!

  38. Vicky April 2, 2018 at 2:05 am #

    Hello Adrian, I successfully wrote the video into file. But when I played the video, I found it played much faster than normal. Do you have any idea why it’s like this?

    • Adrian Rosebrock April 4, 2018 at 12:29 pm #

      It’s likely an issue with the FPS parameter to cv2.VideoWriter. You may need to try different FPS values and play around with it.

  39. Julian April 12, 2018 at 1:19 pm #

    Hey Adrian,

    First, this was an awesome blog. I’ve been looking for something like this for a while.

    Second, I am using a laptop with a built in webcam, but I want to instead use a usb webcam. How could I alter the code to use the usb webcam instead?

    Thank you for your time,


    • Adrian Rosebrock April 13, 2018 at 6:44 am #

      This code will work with either a USB webcam, builtin webcam, or Raspberry Pi camera module.

  40. Rohit sharma June 7, 2018 at 6:09 am #

    If I want output in whole screen instead of splitting the screen into four what should i do?

    I have commented the rest of the three but its only showing output of left top corner.

    output[0:h, 0:w] = frame
    #output[0:h,w:w*2] = R
    #output[h:h, w:w*2] = G
    #output[h:h, 0:w] = B

    I also tried changing the ration but its giving me error

  41. Zubair Ahmed December 12, 2018 at 3:33 am #

    I just ran into this stupid video not saving issue like alot of others and for the life of me I couldn’t figure out what the real issue is after trying few codec/file extension changes, in the end I had to resort to an external screen capturing tool to record video which works

    • Adrian Rosebrock December 13, 2018 at 9:06 am #

      Writing to video with OpenCV can be super frustrating. I’m curious if anyone has used scikit-video? I haven’t given the library a try but I’d consider writing a post on it if there was enough interest.

  42. Ibrahim September 12, 2019 at 5:34 am #

    Any body tried on Ubuntu 16.04 ? I spent many hours and tried alot of combinations but in-vain. ;(. Can someone suggest me or had experienced before ?


  1. Saving key event video clips with OpenCV - PyImageSearch - February 29, 2016

    […] week’s blog post taught us how to write videos to file using OpenCV and Python. This is a great skill to have, but it also raises the […]

Before you leave a comment...

Hey, Adrian here, author of the PyImageSearch blog. I'd love to hear from you, but before you submit a comment, please follow these guidelines:

  1. If you have a question, read the comments first. You should also search this page (i.e., ctrl + f) for keywords related to your question. It's likely that I have already addressed your question in the comments.
  2. If you are copying and pasting code/terminal output, please don't. Reviewing another programmers’ code is a very time consuming and tedious task, and due to the volume of emails and contact requests I receive, I simply cannot do it.
  3. Be respectful of the space. I put a lot of my own personal time into creating these free weekly tutorials. On average, each tutorial takes me 15-20 hours to put together. I love offering these guides to you and I take pride in the content I create. Therefore, I will not approve comments that include large code blocks/terminal output as it destroys the formatting of the page. Kindly be respectful of this space.
  4. Be patient. I receive 200+ comments and emails per day. Due to spam, and my desire to personally answer as many questions as I can, I hand moderate all new comments (typically once per week). I try to answer as many questions as I can, but I'm only one person. Please don't be offended if I cannot get to your question
  5. Do you need priority support? Consider purchasing one of my books and courses. I place customer questions and emails in a separate, special priority queue and answer them first. If you are a customer of mine you will receive a guaranteed response from me. If there's any time left over, I focus on the community at large and attempt to answer as many of those questions as I possibly can.

Thank you for keeping these guidelines in mind before submitting your comment.

Leave a Reply