首页 > 解决方案 > 尝试使用 cheroot flask 和 opencv 向多个客户端广播视频

问题描述

我正在尝试创建从我的 Raspberry Pi 到多个客户端的视频流。Flask 不支持 WSGI 服务器,所以我使用cheroot.wsgi服务器。我使用 noip 创建了一个 ddns 服务器,以便通过 Internet 广播视频流。直到现在,即使我使用 wsgi 服务器,我也只能将视频提供给一个客户端。

这是视频馈线

from flask import Flask, render_template, Response
from camera import VideoCamera
import RPi.GPIO as gpio


gpio.setmode(gpio.BCM)  
gpio.setup(21, gpio.OUT)


app = Flask(__name__)

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')


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



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

@app.route('/background_process_test')
def background_process_test():
    gpio.output(21, gpio.HIGH)

    print ("Hello")
    return ("nothing")

@app.route('/background_process_test2')
def background_process_test2():
    gpio.output(21, gpio.LOW)

    print ("Hello")
    return ("nothing")

if __name__ == '__main__':
    app.run()

这是使用 cheroot 的 wsgi 服务器

尝试:从 cheroot.wsgi 导入服务器作为 WSGIServer,PathInfoDispatcher 除外 ImportError:从cherrypy.wsgiserver 导入 CherryPyWSGIServer 作为 WSGIServer,WSGIPathInfoDispatcher 作为 PathInfoDispatcher 的 print("OK")

from main import app
d = PathInfoDispatcher({'/': app})
server = WSGIServer(('0.0.0.0', 5000), d)
if __name__ == '__main__':
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

捕获相机帧的opencv模块

import cv2

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(0)
        self.video.set(cv2.CAP_PROP_FRAME_WIDTH, 160)
        self.video.set(cv2.CAP_PROP_FRAME_HEIGHT, 200)
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()

    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()

最后是提供视频源的网页

<!doctype html>

<html>
<head>
<!--    <link rel="shortcut icon" href="1.ico" type="image/x-icon" />-->

    <title>jindeath</title>



</head>
<body>



hello
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type=text/javascript>
        $(function() {
          $('a#test').bind('click', function() {
            $.getJSON('/background_process_test',
                function(data) {
              //do nothing
            });
            return false;
          });
        });
                $(function() {
          $('a#test2').bind('click', function() {
            $.getJSON('/background_process_test2',
                function(data) {
              //do nothing
            });
            return false;
          });
        });
</script>

<div class='container'>
    <h3>Test</h3>
        <form>
            <img id="bg" src="{{ url_for('video_feed') }}">
            <a href=# id=test><button class='btn btn-default'>Test</button></a>
            <a href=# id=test2><button class='btn btn-default'>Test</button></a>

        </form>
</body>
</html>

此外,当多个设备连接到页面时,我的 rpi 会使用 100% 的 cpu。有什么建议么

标签: pythonflaskraspberry-pi3cherrypycheroot

解决方案


推荐阅读