修改前代码:
# camera = cv2.VideoCapture(0)
# camera = cv2.VideoCapture('rtsp://admin:admin@192.16.19.2:554/cam/realmonitor?channel=1&subtype=1')
def gen_frames():
frame_count = 0
while True:
camera = cv2.VideoCapture('rtsp://admin:admin@192.168.19.12:554/cam/realmonitor?channel=1&subtype=1')
# size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT)))
success, frame = camera.read() # read the camera frame
if not success:
break
else:
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
# concat frame one by one and show result
@app.route('/mv')
def mv_test():
return '''
<body><div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h3 class="mt-5">Live Streaming</h3>
<img src="{}" width="1280px" height="720px">
<video src="{}" width="100%" type="video/mp4" controls autoplay="autoplay" muted="muted" loop playsinline='' controls="controls">您的浏览器不支持 video 标签 </video>
</div>
</div>
</div>
</body>
'''.format(url_for('video_feed'), url_for('video_feed'))
@app.route('/video_feed')
def video_feed():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(port=5002)这段代码,虽可以显示出画面,但掉帧严重,且会出现中断的情况,不能持久播放。
将代码封装到类中后,效果明显改善。且不中断,能持续播放。
具体的原因,还需要再思考一下。
这也是flask + opencv 实现视频转图片流,到网站前端显示的完整实现示例代码:
from flask import Flask, render_template, Response, url_for
import cv2
import time
class VideoCamera(object):
# 搞成类的模式就不卡了,
def __init__(self):
# 通过opencv获取实时视频流
self.video = cv2.VideoCapture('rtsp://admin:hk888888@192.168.19.12:554/cam/realmonitor?channel=1&subtype=1')
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
# 在这里处理视频帧
cv2.putText(image, "hello", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0))
#
# 因为opencv读取的图片并非jpeg格式,因此要用motion JPEG模式需要先将图片转码成jpg格式图片
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
app = Flask(__name__)
@app.route('/') # 主页
def index():
# jinja2模板,具体格式保存在index.html文件中
return '''
<body><div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h3 class="mt-5">Live Streaming</h3>
<img src="{}" width="1280px" height="720px" style="margin:50px auto">
</div>
</div>
</div>
</body>
'''.format(url_for('video_feed'))
# <video src="{}" width="100%" type="video/mp4" controls autoplay="autoplay" muted="muted" loop playsinline='' controls="controls">您的浏览器不支持 video 标签 </video>
def gen(camera):
while True:
start_t = time.time()
frame = camera.get_frame()
#print('{0}'.format(time.time()-start_t))
# 使用generator函数输出视频流, 每次请求输出的content类型是image/jpeg
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
@app.route('/video_feed') # 这个地址返回视频流响应
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=5000)