How to Build Web Camera Recorder Using OpenCV and Flask

Xiao Ling
Xiao Ling
Aug 28, 2017 · 4 min read

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

Written by

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade