如何使用FastAPI将视频帧和文本返回到HTML页面?

问题描述 投票:0回答:1

使用当前代码,我只能将视频帧发送到网页。我怎样才能在每个帧中发送一些文本并显示它。

FastAPI代码

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代码

<div style= "height:50px"></div>
<img src ="{{ url_for('video') }}" width="50%" />
</div>
python html opencv computer-vision fastapi
1个回答
2
投票

您可以使用

WebSockets
代替,如这个答案(选项2)中所述,以及这个答案这个答案,并将文本和图像字节发送到前端。

工作示例

app.py

from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from websockets.exceptions import ConnectionClosed
from fastapi.templating import Jinja2Templates
import uvicorn
import asyncio
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('.jpg', frame)
                await websocket.send_text("some text")
                await websocket.send_bytes(buffer.tobytes())
            await asyncio.sleep(0.33)
    except (WebSocketDisconnect, ConnectionClosed):
        print("Client disconnected")
 
if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)

模板/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");
            let image = document.getElementById("frame");
            image.onload = function(){
                URL.revokeObjectURL(this.src); // release the blob URL once the image is loaded
            } 
            ws.onmessage = function(event) {
                if (typeof event.data === 'string') 
                    document.getElementById("textArea").innerHTML = event.data;
                else
                    image.src = URL.createObjectURL(event.data);
            };
        </script>
    </body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.