Home > OS >  How to return video frame and text to HTML page using FastAPI?
How to return video frame and text to HTML page using FastAPI?

Time:05-01

With the current code, I can only send the video frame to the webpage. How can I also send some text along with each frame and have it displayed.

FastAPI code

def generate_frames(cap,i):
    while True:
        success,frame = cap.read()
        if not success:
            break
        else:
                # Reshape image
                im_arr = cv2.imencode('.jpg', frame)[1]
                cv2.waitKey(50)
                print(loa[i]) //text to be displayed along with image
                i = i   1
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n'   bytearray(im_arr)   b'\r\n')


@app.get('/video')
def video():
    i = 0
    cap = cv2.VideoCapture('C:\\Users\\ryanv_k78mbsh\\Desktop\\FINAL\\MovenetTest\\animation.gif')
    return StreamingResponse(generate_frames(cap,i),media_type = 'multipart/x-mixed-replace; boundary=frame')

HTML code that receives and displays the video frame

<div style= "height:50px"></div>
<img src ="{{ url_for('video') }}" width="50%" />
</div>

CodePudding user response:

You could use WebSockets instead, as described in this answer (Option 2), and send both the text and image bytes to the frontend. Example below:

app.py

from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from fastapi.templating import Jinja2Templates
import uvicorn
import cv2

app = FastAPI()
camera = cv2.VideoCapture(0,cv2.CAP_DSHOW)
templates = Jinja2Templates(directory="templates")

@app.get('/')
def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.websocket("/ws")
async def get_stream(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            success, frame = camera.read()
            if not success:
                break
            else:
                ret, buffer = cv2.imencode('.png', frame)
                await websocket.send_text("some text")
                await websocket.send_bytes(buffer.tobytes())
    except WebSocketDisconnect:
        print("Client disconnected")   
 
if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)

templates/index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Live Streaming</title>
    </head>
    <body>
        <img id="frame" src="">
        <div id="textArea"></div>
        <script>
            let ws = new WebSocket("ws://localhost:8000/ws");
            ws.onmessage = function(event) {
                if (typeof event.data === 'string') 
                    document.getElementById("textArea").innerHTML = event.data;
                else{
                    let blob = new Blob([event.data])
                    let blobURL = URL.createObjectURL(blob);
                    let image = document.getElementById("frame");
                    image.src = blobURL;
                }
            };
        </script>
    </body>
</html>
  • Related