How to Build Web Camera Recorder Using OpenCV and Flask

Xiao Ling
4 min readAug 28, 2017

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.

How to Use OpenCV to Record a Video

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

import numpy as npimport cv2cap = cv2.VideoCapture(0)# Define the codec and create VideoWriter objectfourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))while(cap.isOpened()):ret, frame = cap.read()if ret==True:frame = cv2.flip(frame,0)# write the flipped frameout.write(frame)cv2.imshow('frame',frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break# Release everything if job is finishedcap.release()out.release()cv2.destroyAllWindows()

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))

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:

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

How to Build Camera Recorder in Web Browser

The source code of video_streaming_with_flask_example is good but limited. It keeps sending responses that contain image data and never ends.

def get_frame(self):success, image = self.video.read()# 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_cameraglobal global_frameif video_camera == None:video_camera = VideoCamera()while True:frame = video_camera.get_frame()if frame != None:global_frame = frameyield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')else: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.

Client:

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

Server:

@app.route('/record_status', methods=['POST'])def record_status():global video_cameraif video_camera == None:video_camera = VideoCamera()json = request.get_json()status = json['status']if status == "true":video_camera.start_record()return jsonify(result="started")else:video_camera.stop_record()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)self.name = nameself.isRunning = Trueself.cap = camerafourcc = cv2.VideoWriter_fourcc(*'MJPG')self.out = cv2.VideoWriter('./static/video.avi',fourcc, 20.0, (640,480))def run(self):while self.isRunning:ret, frame = self.cap.read()if ret:self.out.write(frame)self.out.release()def stop(self):self.isRunning = Falsedef __del__(self):self.out.release()

Run the app:

python server.py

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

To get rid of the exception, enable threaded mode:

if __name__ == '__main__':app.run(host='0.0.0.0', threaded=True)

Or use Python 3 to run the app.

Source Code

https://github.com/yushulx/web-camera-recorder

Originally published at www.codepool.biz on August 28, 2017.

--

--

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover