基于flask与opencv制作一个视频监控小程序:
主要实现引入视频流到web页面
import cv2
import numpy as np
from flask import Flask, render_template, Response
app = Flask(__name__)
video_writer = None
class Camera:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.camera = cv2.VideoCapture(0)
return cls._instance
def __del__(self):
self.camera.release()
def get_frame(self):
success, frame = self.camera.read()
if not success:
return None
else:
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
return frame
camera = Camera()
def convert_bytes_to_frame(frame_bytes):
# 将bytes类型的图像数据解码为OpenCV图像格式
frame_array = np.frombuffer(frame_bytes, dtype=np.uint8)
frame = cv2.imdecode(frame_array, flags=cv2.IMREAD_COLOR)
return frame
# 获取视频流
def get_video_stream():
global camera,video_writer
while True:
if camera is None:
break
frame = camera.get_frame()
if frame is None:
break
else:
if video_writer is not None:
video_writer.write(convert_bytes_to_frame(frame))
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
# 关闭摄像头
def close_camera():
global camera
camera = None
@app.route('/open_camera', methods=['POST'])
def open_camera_route():
global camera
camera = Camera()
return Response(get_video_stream(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/close_camera', methods=['POST'])
def close_camera_route():
close_camera()
return 'Camera closed'
@app.route('/')
def index():
return render_template('index3.html')
@app.route('/video_feed')
def video_feed():
return Response(get_video_stream(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/start_recording')
def start_recording():
global video_writer
video_writer = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), 20.0, (640, 480))
return 'Recording started'
@app.route('/stop_recording')
def stop_recording():
global video_writer
video_writer.release()
video_writer = None
return 'Recording stopped'
if __name__ == '__main__':
app.run(debug=True)
前台页面写法
<!DOCTYPE html>
<html>
<head>
<title>Video Streaming</title>
</head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<body>
<h1>监控视频流</h1>
<img src="{{ url_for('video_feed') }}" width="640" height="480">
<br>
<button id="open" onclick="openCamera(),location.reload();">打开摄像头</button>
<button id="close" onclick="closeCamera()">关闭摄像头</button>
<br>
<a href="{{ url_for('start_recording') }}">开始录像</a>
<a href="{{ url_for('stop_recording') }}">结束录像</a>
<script>
function openCamera() {
$.ajax({
url: '/open_camera',
type: 'POST',
success: function(response) {
console.log(response);
}
});
}
function closeCamera() {
$.ajax({
url: '/close_camera',
type: 'POST',
success: function(response) {
console.log(response);
}
});
}
</script>
</body>
</html>