How to Build Web Camera Recorder Using OpenCV and Flask

Recently, I was inspired by a blog post “Python Live Video Streaming Example” and thinking whether it is possible to save the camera streaming to a video file. Based on the example code, I managed to figure out a solution. In this post, I want to share the process of building the web camera recorder using OpenCV and Flask.

web camera recorder

How to Use OpenCV to Record a Video

Let’s start with the code snippet posted on OpenCV website:

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))


    ret, frame =
    if ret==True:
        frame = cv2.flip(frame,0)
        # write the flipped frame

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

# Release everything if job is finished

After running the code on Windows, I got a 0KB file. The reason is the codec does not exist in my Windows 10. Replace fourcc with -1 to check the available codec list:

out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))

windows video codec

Instead of XVID, using MJPG will work.

fourcc = cv2.VideoWriter_fourcc(*'MJPG')

MJPG codec results in high size video. To get a smaller size, we need to install X264, which is not in the codec list by default.

Change codec to X264:

fourcc = cv2.VideoWriter_fourcc(*'X264')

Once you run the app, an annoying log window will pop up:

x264 log window

I have found the solution here. Open Windows registry and set log_level value 0.

close x264 log window

How to Build Camera Recorder in Web Browser

The source code of video_streaming_with_flask_example is handy.

def get_frame(self):
        success, image =
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

In my case, I have to save camera instance globally for video recording.

def video_stream():
    global video_camera 
    global global_frame

    if video_camera == None:
        video_camera = VideoCamera()
    while True:
        frame = video_camera.get_frame()

        if frame != None:
            global_frame = frame
            yield (b'--frame\r\n'
                    b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
            yield (b'--frame\r\n'
                            b'Content-Type: image/jpeg\r\n\r\n' + global_frame + b'\r\n\r\n')


Use XMLHttpRequest to start and stop video recording event.


    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            // alert(xhr.responseText);
    }"POST", "/record_status");
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.send(JSON.stringify({ status: "true" }));


@app.route('/record_status', methods=['POST'])
def record_status():
    global video_camera 
    if video_camera == None:
        video_camera = VideoCamera()

    json = request.get_json()

    status = json['status']

    if status == "true":
        return jsonify(result="started")
        return jsonify(result="stopped")

Every time the event is triggered, create a new thread to save camera stream to a video file.

class RecordingThread (threading.Thread):
    def __init__(self, name, camera):
        threading.Thread.__init__(self) = name
        self.isRunning = True

        self.cap = camera
        fourcc = cv2.VideoWriter_fourcc(*'MJPG')
        self.out = cv2.VideoWriter('./static/video.avi',fourcc, 20.0, (640,480))

    def run(self):
        while self.isRunning:
            ret, frame =
            if ret:


    def stop(self):
        self.isRunning = False

    def __del__(self):

Run the app:


Note: if you are using Python 2, you will see the socket connection issue:

python server error

To get rid of the exception, enable threaded mode:

if __name__ == '__main__':'', threaded=True)

Or use Python 3 to run the app.

streaming video recorder

Source Code

  • Vamsi Tungala

    problem is solved after updating the numpy. but sometimes video is blinking and getting the output like below image.
    what would be the problem?
    is there any solution for this?

  • Vamsi Tungala

    i am getting the following error what should i do?

    * Running on (Press CTRL+C to quit) – – [17/Feb/2018 17:25:19] “GET / HTTP/1.1” 200 – – – [17/Feb/2018 17:25:19] “GET /static/recorder.js HTTP/1.1” 304 – – – [17/Feb/2018 17:25:19] “GET /video_viewer HTTP/1.1” 500 –
    Error on request:
    Traceback (most recent call last):
    File “/usr/local/lib/python3.4/dist-packages/werkzeug/”, line 270, in run_wsgi
    File “/usr/local/lib/python3.4/dist-packages/werkzeug/”, line 260, in execute
    for data in application_iter:
    File “/usr/local/lib/python3.4/dist-packages/werkzeug/”, line 870, in __next__
    return self._next()
    File “/usr/local/lib/python3.4/dist-packages/werkzeug/”, line 82, in _iter_encoded
    for item in iterable:
    File “/home/pi/web-camera-recorder-master/”, line 38, in video_stream
    frame = video_camera.get_frame()
    File “/home/pi/web-camera-recorder-master/”, line 63, in get_frame
    return jpeg.tobytes()
    AttributeError: ‘numpy.ndarray’ object has no attribute ‘tobytes’