我构建了这个 flask 应用程序来直播安全摄像头,并且直播与屏幕截图功能一起工作,但是当开始录制时它崩溃了,但有几次相同的代码它工作并在此处保存了视频代码。使用 js 的 html 文件。
from flask import Flask, render_template, Response, request
import cv2
import os
import time
import threading
import requests
app = Flask(__name__)
# Define the IP cameras
cameras = [
{'url': 'rtsp://****:*****@******', 'name': 'Camera 1'},
{'url': 'rtsp://****:*****@******', 'name': 'Camera 2'},
{'url': 'rtsp://****:*****@******', 'name': 'Camera 3'},
{'url': 'rtsp://****:*****@******', 'name': 'Camera 4'}
]
# Create a VideoCapture object for each camera
capture_objs = [cv2.VideoCapture(cam['url']) for cam in cameras]
stop_events = {i: threading.Event() for i in range(len(cameras))}
# Define the directory to save the recorded videos
recording_dir = os.path.join(os.getcwd(), 'recordings')
# Ensure the recording directory exists
if not os.path.exists(recording_dir):
os.makedirs(recording_dir)
# Define the function to capture and save a video
def record_video(camera_index, stop_recording):
# Define the codec and file extension
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
file_extension = '.mp4'
# Get the current timestamp for the filename
timestamp = time.strftime("%Y%m%d-%H%M%S")
# Define the filename and path
filename = f'{cameras[camera_index]["name"]}_{timestamp}{file_extension}'
filepath = os.path.join(recording_dir, filename)
# Create a VideoWriter object to save the video
width = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(capture_objs[camera_index].get(cv2.CAP_PROP_FPS))
video_writer = cv2.VideoWriter(filepath, fourcc, fps, (width, height))
# Capture frames and write them to the file
while True:
if stop_recording.is_set():
break # stop recording if stop_recording is set
ret, frame = capture_objs[camera_index].read()
if ret:
video_writer.write(frame)
else:
break
# Release the VideoWriter object and the VideoCapture object
video_writer.release()
capture_objs[camera_index].release()
@app.route('/')
def index():
# Render the index page with the list of cameras
return render_template('index.html', cameras=cameras)
def generate(camera_index):
# Generate frames from the video feed
while True:
ret, frame = capture_objs[camera_index].read()
if not ret:
break
# Encode the frame as JPEG
_, jpeg = cv2.imencode('.jpg', frame)
# Yield the frame as a Flask response
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n')
@app.route('/video_feed')
def video_feed():
# Get the camera index from the request arguments
camera_index = int(request.args.get('camera_index'))
# Generate the video feed
return Response(generate(camera_index),
mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/record', methods=['POST'])
def record():
# Get the camera index from the request form
camera_index = int(request.form['camera_index'])
stop_recording = stop_events[camera_index] # get the stop_recording event for the camera
thread = threading.Thread(target=record_video, args=(camera_index, stop_recording))
thread.start() # start a thread to record video
# Return a response indicating that the recording has started
return 'Recording started.'
@app.route('/stop_record', methods=['POST'])
def stop_record():
# Get the camera index from the request form
camera_index = int(request.form['camera_index'])
# Set the stop_recording event for the corresponding camera thread
stop_events[camera_index].set()
# Return a response indicating that recording has been stopped
return 'Recording stopped.'
@app.route('/screenshot', methods=['POST'])
def take_screenshot():
# Take a screenshot of the video stream and save it as a file
camera = capture_objs[int(request.form['camera_id'])]
success, frame = camera.read()
if success:
timestamp = time.strftime("%Y%m%d-%H%M%S")
filename = f'screenshot_{timestamp}.jpg'
cv2.imwrite(filename, frame)
return 'Screenshot taken and saved'
else:
return 'Failed to take screenshot'
if __name__ == '__main__':
app.run()
我尝试将 ffmpeg 更新到最新版本并安装了 pip install opencv-python-headless 并安装了 pip install opencv-python 但大多数时候我都遇到了这个崩溃代码
* Serving Flask app 'run'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [17/May/2023 13:24:11] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:44] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -
[h264 @ 0x5605285fc5c0] error while decoding MB 28 29, bytestream -9
[h264 @ 0x560529110040] error while decoding MB 15 37, bytestream -6
[h264 @ 0x560528624980] error while decoding MB 45 45, bytestream -23
[h264 @ 0x5605286f1900] error while decoding MB 50 34, bytestream -7
[h264 @ 0x5605285fc5c0] error while decoding MB 25 9, bytestream -17
[h264 @ 0x5605292b0080] error while decoding MB 28 41, bytestream -5
[h264 @ 0x560528660040] error while decoding MB 101 45, bytestream -17
[h264 @ 0x5605285fc5c0] error while decoding MB 42 44, bytestream -5
[h264 @ 0x5605286f1900] error while decoding MB 118 42, bytestream -9
[h264 @ 0x560529110040] error while decoding MB 92 43, bytestream -5
[h264 @ 0x560528660040] error while decoding MB 99 34, bytestream -11
[h264 @ 0x56052932b0c0] error while decoding MB 92 36, bytestream -13
[h264 @ 0x560528667ac0] error while decoding MB 44 54, bytestream -5
[h264 @ 0x560529110040] error while decoding MB 93 33, bytestream -7
[h264 @ 0x5605286dd880] error while decoding MB 27 37, bytestream -19
[h264 @ 0x560528660040] error while decoding MB 66 56, bytestream -9
127.0.0.1 - - [17/May/2023 13:36:45] "POST /record HTTP/1.1" 200 -
Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:175
Aborted (core dumped)