0
votes

I'm now doing for a project that captures video frame from webcam, and then send to the server together with additional data (now I use generated random number for testing) and show in the webpage at the same time.

Before that, the display of real-time video and data, and sending to server for storage can be done separately. However, when I tried to integrate them together, I found that the error always says as follows:

werkzeug :: INFO :: 192.168.0.103 - - [05/Feb/2020 22:03:10] "GET /video_feed HTTP/1.1" 500 - Traceback (most recent call last): File "/usr/lib/python3/dist-packages/flask/app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "/usr/lib/python3/dist-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request return self.view_functionsrule.endpoint TypeError: video_feed() missing 1 required positional argument: 'input_frame' werkzeug :: INFO :: 192.168.0.103 - - [05/Feb/2020 22:03:10] "GET /data_feed HTTP/1.1" 500 - Traceback (most recent call last): File "/usr/lib/python3/dist-packages/flask/app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "/usr/lib/python3/dist-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request return self.view_functionsrule.endpoint TypeError: data_feed() missing 1 required positional argument: 'input_data'

I have tried to spot out the root cause many times, finding that it should be related to the inner function, but I still cannot fix it. Hope anyone can help through the following code. Thanks!

Edit:

I have followed the reply from Gioachino Bartolotta to add the parameter for passing to. However, new error comes with the followings:

Traceback (most recent call last) File "/usr/lib/python3/dist-packages/flask/app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "/usr/lib/python3/dist-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request return self.view_functionsrule.endpoint File "/home/pi/pilotdrive_poc/streaming/webstreaming_viewer.py", line 30, in index return render_template("index.html") File "/usr/lib/python3/dist-packages/flask/templating.py", line 135, in render_template context, ctx.app) File "/usr/lib/python3/dist-packages/flask/templating.py", line 117, in _render rv = template.render(context) File "/usr/lib/python3/dist-packages/jinja2/asyncsupport.py", line 76, in render return original_render(self, *args, **kwargs) File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 1008, in render return self.environment.handle_exception(exc_info, True) File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 780, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/jinja2/_compat.py", line 37, in reraise raise value.with_traceback(tb) File "/home/pi/pilotdrive_poc/streaming/templates/index.html", line 9, in top-level template code File "/usr/lib/python3/dist-packages/flask/helpers.py", line 356, in url_for return appctx.app.handle_url_build_error(error, endpoint, values) File "/usr/lib/python3/dist-packages/flask/app.py", line 2061, in handle_url_build_error reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/helpers.py", line 345, in url_for force_external=external) File "/usr/lib/python3/dist-packages/werkzeug/routing.py", line 1776, in build raise BuildError(endpoint, values, method, self) werkzeug.routing.BuildError: Could not build url for endpoint 'video_feed'. Did you forget to specify values ['input_frame']?

I'm wondering what's wrong together with my index.html? I also attached here now. Thanks again!

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>
1

1 Answers

0
votes

I think you are missing to declare your arguments into the URL.

What I mean is:

you have

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

and

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

Now the error you get complains about that something is missing, and what is missing in your route is the parameter that you are passing into the underlying function used by the route. To get rid of the error you have to rewrite the route like this, and then you have to call the URLs accordingly.

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

and

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

Of course you can setup a default value if the argument has not been specified.