基于 Flask RTSP的视频流Web显示

参考:

从【OpenCV】利用Flask+Python+OpenCV实现摄像头读取图像帧网页视频流_小风

基于OpenCV + flask 实现的网络实时视频流传输 | 附源码

flask+python 实时视频流输出到前台

【opencv-python】利用opencv读取rtsp的实时帧_frootguo的博客-CSDN博客_opencv读取rtmp

ython调用海康威视网络相机之——python读取相机rtsp码流显示画面

使用opencv-python读取多个(海康\大华)网络摄像头的视频流,解决实时读取延迟问题_不羁少年!的博客 

1、FLASK安装

月快速上手_Flask中文网P

Pycharm 2021.3.3 中文输入,测试了很多无效。最好采用以下:

Ubuntu 20.04 系统自带中文输入法在PyCharm只能输入3个字母的问题_依巴谷32349的博客-CSDN博客

2、运行

Pycharm中

菜单Run -> run...

错误1:

SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte

中文编码问题,用UTF8

错误2:ImportError: numpy.core.multiarray failed to import

安装

pip install numpy==1.16.4

pip install matplotlib==3.4.3  (最新3.5.1要求numpy>1.17)

执行结果

FLASK_APP = app.py
FLASK_ENV = development
FLASK_DEBUG = 0
In folder /home/robot/anaconda3/envs/tf/flask
/home/robot/anaconda3/envs/tf/bin/python -m flask run
 * Serving Flask app 'app.py' (lazy loading)
 * Environment: development
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

在浏览输入http://127.0.0.1:5000/

3、代码

 app.py

# -*-coding:utf-8-*-
from flask import Flask, render_template, Response
from RtspCapture import RtspCapture

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


def gen(rtsp):
    while True:
        this_frame = rtsp.cap_frame()
        if this_frame is not None:
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + this_frame + b'\r\n')


@app.route('/video_feed')
def video_feed():
    cap = RtspCapture()
    cap.start()
    return Response(gen(cap),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9011, threaded=True)

RtspCapture.py

import os
import cv2
import time
import threading
import queue


class RtspCapture(object):
    read_thread = None  # background thread that reads frames from camera
    get_thread = None  # 从imglist中获取帧的进程
    pop_frame = None  # current frame is stored here by background thread
    last_access = 0  # time of last client access to the camera
    imgList = None
    url = "rtsp://admin:admin888@192.168.1.64:554/h264/ch1/sub/av_stream"
    top = 100
    lock = None

    def __init__(self):
        top = 100

    def start(self):
        # self.imgList = Manager().list()
        self.imgList = queue.Queue(self.top)
        self.lock = threading.Lock()
        if self.read_thread is None:
            # start background frame thread
            self.read_thread = threading.Thread(target=self.read)
            self.read_thread.start()

        if self.get_thread is None:
            self.last_access = time.time()
            self.get_thread = threading.Thread(target=self.get_frame)
            self.get_thread.start()

    def set_url(self, src):
        self.url = src

    # 向共享缓冲栈中写入数据:
    def read(self):
        print('Process to write: %s' % os.getpid())
        cap = cv2.VideoCapture(self.url)
        while True:
            _, img = cap.read()
            if _:
                if self.imgList.full():
                    self.imgList.get()
                self.imgList.put(img)

    # 在缓冲栈中读取数据:
    def get_frame(self):
        print('Process to get: %s' % os.getpid())
        while True:
            if not self.imgList.empty():
                self.lock.acquire()
                value = self.imgList.get(False)  # 非阻塞方法
                self.pop_frame = value
                self.lock.release()

    def cap_frame(self):
        if self.pop_frame is None:
            print('frame is None')
        else:
            # print('set frame')
            self.lock.acquire()
            jpg = cv2.imencode('.jpg', self.pop_frame)[1].tobytes()
            self.lock.release()
            return jpg

index.html

<html>
  <head>
    <title>视频流演示</title>
  </head>
  <body>
    <h1>视频流演示</h1>
    <img src="{{ url_for('video_feed') }}">
  </body>
</html>

遗留问题:

延迟暂时没有解决

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值