Streaming video from camera in FastAPI results in frozen image after first frame

mar*_*ius 6 python opencv flask fastapi

I am trying to stream video from a camera using FastAPI, similar to an example I found for Flask. In Flask, the example works correctly, and the video is streamed without any issues. However, when I try to replicate the same functionality in FastAPI, I encounter a problem where the video stream freezes after the first frame.

I have followed the example provided in this Flask code https://www.pyimagesearch.com/2019/09/02/opencv-stream-video-to-web-browser-html-page/ but when I adapt it to FastAPI, the video only displays the first frame and then remains frozen. I suspect there might be a difference in how FastAPI handles streaming responses compared to Flask.

Example in Flask (Works normally):

def generate():
    # grab global references to the output frame and lock variables
    global outputFrame, lock
    # loop over frames from the output stream
    while True:
        # wait until the lock is acquired
        with lock:
            # check if the output frame is available, otherwise skip
            # the iteration of the loop
            if outputFrame is None:
                continue
            # encode the frame in JPEG format
            (flag, encodedImage) = cv2.imencode(".jpg", outputFrame)
            # ensure the frame was successfully encoded
            if not flag:
                continue
        # 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')

@app.route("/")
def video_feed():
    # return the response generated along with the specific media
    # type (mime type)
    return Response(generate(),
                    mimetype="multipart/x-mixed-replace; boundary=frame")
Run Code Online (Sandbox Code Playgroud)

Here is my FastAPI code:

def generate():
    # grab global references to the output frame and lock variables
    global outputFrame, lock
    # loop over frames from the output stream
    while True:
        # wait until the lock is acquired
        with lock:
            # check if the output frame is available, otherwise skip
            # the iteration of the loop
            if outputFrame is None:
                continue
            # encode the frame in JPEG format
            (flag, encodedImage) = cv2.imencode(".jpg", outputFrame)
            # ensure the frame was successfully encoded
            if not flag:
                continue
        # yield the output frame in the byte format
        yield b''+bytearray(encodedImage)


@app.get("/")
def video_feed():
    # return the response generated along with the specific media
    # type (mime type)
    # return StreamingResponse(generate())
    return StreamingResponse(generate(), media_type="image/jpeg")
Run Code Online (Sandbox Code Playgroud)

I have also reviewed the question Video Streaming App using FastAPI and OpenCV, but I couldn't find a solution that addresses my specific issue.

Could someone please help me understand what modifications I need to make in my FastAPI code to ensure that the video stream is continuously updated and not frozen after the first frame? I would appreciate any guidance or suggestions. Thank you!

mar*_*ius 10

在这里发帖后,我想出了如何解决它。

video_feed函数中,media_type参数中,只是按照flask中的方式来放置:

@app.get("/")
def video_feed():
    # return the response generated along with the specific media
    # type (mime type)
    # return StreamingResponse(generate())
    return StreamingResponse(generate(), media_type="multipart/x-mixed-replace;boundary=frame")
Run Code Online (Sandbox Code Playgroud)

并在函数中生成:

yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
               bytearray(encodedImage) + b'\r\n')
Run Code Online (Sandbox Code Playgroud)

我的完整代码:

http://github.com/mpimentel04/rtsp_fastapi