【问题标题】:Python Flask threaded program cannot display streaming data in two app routesPython Flask 线程程序无法在两个应用程序路由中显示流数据
【发布时间】:2020-05-21 11:40:44
【问题描述】:

我现在正在做一个项目,从网络摄像头捕获视频帧,然后与附加数据一起发送到服务器(现在我使用生成的随机数进行测试)并同时显示在网页中。

在此之前,实时视频和数据的显示和发送到服务器存储可以分开进行。但是,当我尝试将它们集成在一起时,我发现错误总是如下所示:

werkzeug :: INFO :: 192.168.0.103 - - [05/Feb/2020 22:03:10] "GET /video_feed HTTP/1.1" 500 - 回溯(最后一次调用):文件 调用中的“/usr/lib/python3/dist-packages/flask/app.py”,第 2309 行 返回 self.wsgi_app(environ, start_response) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 2295 行,在 wsgi_app 响应 = self.handle_exception(e) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1741 行,在 处理异常 reraise(exc_type, exc_value, tb) 文件“/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 提高值文件“/usr/lib/python3/dist-packages/flask/app.py”,第 2292 行,在 wsgi_app response = self.full_dispatch_request() 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1815 行,在 full_dispatch_request rv = self.handle_user_exception(e) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1718 行,在 处理用户异常 reraise(exc_type, exc_value, tb) 文件“/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 在 full_dispatch_request 中提高值文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1813 行 rv = self.dispatch_request() 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1799 行,在 dispatch_request 返回 self.view_functionsrule.endpoint TypeError: video_feed() 缺少 1 个必需的位置参数: 'input_frame' werkzeug :: INFO :: 192.168.0.103 - - [05/Feb/2020 22:03:10]“GET /data_feed HTTP/1.1”500 - 回溯(最近的调用 最后):文件“/usr/lib/python3/dist-packages/flask/app.py”,行 2309,在通话中 返回 self.wsgi_app(environ, start_response) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 2295 行,在 wsgi_app 响应 = self.handle_exception(e) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1741 行,在 处理异常 reraise(exc_type, exc_value, tb) 文件“/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 提高值文件“/usr/lib/python3/dist-packages/flask/app.py”,第 2292 行,在 wsgi_app response = self.full_dispatch_request() 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1815 行,在 full_dispatch_request rv = self.handle_user_exception(e) 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1718 行,在 处理用户异常 reraise(exc_type, exc_value, tb) 文件“/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 在 full_dispatch_request 中提高值文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1813 行 rv = self.dispatch_request() 文件“/usr/lib/python3/dist-packages/flask/app.py”,第 1799 行,在 dispatch_request 返回 self.view_functionsrule.endpoint TypeError: data_feed() 缺少 1 个必需的位置参数: '输入数据'

我多次尝试找出根本原因,发现它应该与内部功能有关,但我仍然无法解决它。希望任何人都可以通过以下代码提供帮助。谢谢!

编辑:

我已经按照 Gioachino Bartolotta 的回复添加了传递给的参数。但是,新错误带有以下内容:

Traceback(最近一次调用最后一次)文件 调用中的“/usr/lib/python3/dist-packages/flask/app.py”,第 2309 行 返回 self.wsgi_app(environ, start_response) 文件 “/usr/lib/python3/dist-packages/flask/app.py”,第 2295 行,在 wsgi_app 中 response = self.handle_exception(e) 文件 “/usr/lib/python3/dist-packages/flask/app.py”,第 1741 行,在 handle_exception reraise(exc_type, exc_value, tb) 文件 “/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 提高价值文件“/usr/lib/python3/dist-packages/flask/app.py”,行 2292,在 wsgi_app response = self.full_dispatch_request() 文件中 “/usr/lib/python3/dist-packages/flask/app.py”,第 1815 行,在 full_dispatch_request rv = self.handle_user_exception(e) 文件 “/usr/lib/python3/dist-packages/flask/app.py”,第 1718 行,在 handle_user_exception reraise(exc_type, exc_value, tb) 文件 “/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 提高价值文件“/usr/lib/python3/dist-packages/flask/app.py”,行 1813,在full_dispatch_request rv = self.dispatch_request() 文件中 “/usr/lib/python3/dist-packages/flask/app.py”,第 1799 行,在 dispatch_request 返回 self.view_functionsrule.endpoint 文件 “/home/pi/pilotdrive_poc/streaming/webstreaming_viewer.py”,第 30 行, 在索引中返回 render_template("index.html") 文件 “/usr/lib/python3/dist-packages/flask/template.py”,第 135 行,在 render_template 上下文,ctx.app) 文件 “/usr/lib/python3/dist-packages/flask/templating.py”,第 117 行,在 _render rv = template.render(context) 文件“/usr/lib/python3/dist-packages/jinja2/asyncsupport.py”,第 76 行,在 渲染返回 original_render(self, *args, **kwargs) 文件 “/usr/lib/python3/dist-packages/jinja2/environment.py”,第 1008 行,在 渲染返回 self.environment.handle_exception(exc_info, True) 文件 “/usr/lib/python3/dist-packages/jinja2/environment.py”,第 780 行,在 handle_exception reraise(exc_type, exc_value, tb) 文件 “/usr/lib/python3/dist-packages/jinja2/_compat.py”,第 37 行,在 reraise raise value.with_traceback(tb) 文件 “/home/pi/pilotdrive_poc/streaming/templates/index.html”,第 9 行,在 顶级模板代码文件 “/usr/lib/python3/dist-packages/flask/helpers.py”,第 356 行,在 url_for return appctx.app.handle_url_build_error(错误,端点, 值)文件“/usr/lib/python3/dist-packages/flask/app.py”,第 2061 行, 在 handle_url_build_error reraise(exc_type, exc_value, tb) 文件中 “/usr/lib/python3/dist-packages/flask/_compat.py”,第 35 行,在 reraise 提高价值文件“/usr/lib/python3/dist-packages/flask/helpers.py”, 第 345 行,在 url_for force_external=external) 文件中 “/usr/lib/python3/dist-packages/werkzeug/routing.py”,第 1776 行,在 build raise BuildError(endpoint, values, method, self) werkzeug.routing.BuildError:无法为端点构建 url 'video_feed'。您是否忘记指定值 ['input_frame']?

我想知道我的 index.html 出了什么问题?我现在也附在这里。再次感谢!

webstreaming_viewer.py

# USAGE
# python webstreaming.py --ip 0.0.0.0 --port 8000

# import the necessary packages
from vidgear.gears import VideoGear, NetGear
from flask import Response
from flask import Flask, current_app
from flask import render_template
from flask import jsonify
from random import random
import threading
import argparse
import datetime
import imutils
import time
import cv2

# initialize the output frame and a lock used to ensure thread-safe
# exchanges of the output frames (useful for multiple browsers/tabs
# are viewing tthe stream)

server_address='206.189.144.234'
options_cam={"CAP_PROP_FRAME_WIDTH":640,"CAP_PROP_FRAME_HEIGHT":480,"CAP_PROP_FPS":60}
options_client={'bidirectional_mode':True,'compression_format':'.jpg','compression_param':[cv2.IMWRITE_JPEG_QUALITY,80],'flag':0,'copy':False,'track':False}
stream=VideoGear(enablePiCamera=False,logging=False,**options_cam).start()
client=NetGear(address=server_address, port='20001', protocol='tcp', pattern=1, receive_mode=False, logging=True, **options_client)

app=Flask(__name__)

@app.route("/")
def index():
    # return the rendered template
    return render_template("index.html")

@app.route("/data_feed/<input_data>")
def data_feed(input_data):
    def dataStream(input_data):
        while True:
            print("get_data={}".format(input_data))
            yield "data: {}\n\n".format(input_data)
            time.sleep(1)
    return Response(dataStream(input_data), mimetype="text/event-stream")

@app.route("/video_feed/<input_frame>")
def video_feed(input_frame):
    # return the response generated along with the specific media
    # type (mime type)
    def display_frame(input_frame):
        while True:
            print("get_frame={}".format(input_frame))
            # encode the frame in JPEG format
            (flag, encodedImage) = cv2.imencode(".jpg", input_frame)

            # yield the output frame in the byte format
            yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + 
                bytearray(encodedImage) + b'\r\n')
    return Response(display_frame(input_frame),
        mimetype = "multipart/x-mixed-replace; boundary=frame")

def get_realtime_stream():
    while True:
        frame = stream.read()
        data_stream=round(random()*10,3)
        client.send(frame,message=data_stream)
        video_feed(frame)
        data_feed(data_stream)
    stream.stop()
    client.close()

# check to see if this is the main thread of execution
if __name__ == '__main__':
    t = threading.Thread(target=get_realtime_stream)
    t.start()

    app.run(host='0.0.0.0',port=8000,debug=True,threaded=True,use_reloader=False)

index.html

<html>
    <head>
        <title>Pi Video Surveillance</title>
    </head>
    <body>
        <div style="float: left; width: 100%">
            <div style="float: left; width: 700">
                <h1>Pi Video Surveillance</h1>
                    <img src="{{ url_for('video_feed') }}">
            </div>
            <div style="float: left">
                <h1>real-time data</h1>
                <iframe src="{{ url_for('data_feed') }}">
            </div>
        </div>
        <div>
            <div>
                <h1>Car control panel</h1>
            </div>
        </div>
    </body>
</html>

【问题讨论】:

    标签: python-3.x flask


    【解决方案1】:

    我认为你没有在 URL 中声明你的参数。

    我的意思是:

    你有

    @app.route("/data_feed") def data_feed(input_data)

    @app.route("/video_feed") def data_feed(input_frame)

    现在你得到的错误是抱怨缺少某些东西,而你的路由中缺少的是你传递给路由使用的底层函数的参数。 要消除错误,您必须像这样重写路由,然后必须相应地调用 URL。

    @app.route("/data_feed/<input_data>") def data_feed(input_data)

    @app.route("/video_feed/<input_frame>") def data_feed(input_frame)

    当然,如果没有指定参数,你可以设置一个默认值。

    【讨论】:

    • 感谢您的回复。但是在实现它时,我发现错误消息说“werkzeug.routing.BuildError:无法为端点'video_feed'构建url。您是否忘记指定值['input_frame']?”。 index.html 中有什么我遗漏的吗?再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2019-08-11
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多