如何使用 Websocket 将视频媒体流从 React js 发送到 Python?

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

我的目标是使用 websocket 将用户的视频流作为数组缓冲区发送到 python。我对如何使 getUserMedia 流式传输数组并使用 fastapi websocket 将其发送到 python 感到困惑。

我正在分享我尝试的代码的一些重要部分,希望有人帮助我解决这个问题。

提前致谢。

我尝试的代码:

React js--

const userStream = useRef([]);

useEffect(() => {
  navigator.mediaDevices.getUserMedia({ audio: false, video: true }).then(stream => {
  userStream.current.srcobject = stream;

无法弄清楚创建 userStream 数组对象的过程

  var socket = new WebSocket('ws://localhost:8000/ws')
  socket.onopen = () => socket.send(userStream.current.srcobject)

  socket.onmessage = function (event) {
    console.log("[message] Data received from server:");
    if (event.data !== undefined && event.data !== null) {
      console.log(event.data)
    }
  }

  socket.onclose = () => {
    console.log("Connection Closed!");
  };
    
  socket.onerror = () => {
    console.log("WS Error");
  };

  return () => {
    socket.close();
  };
    });

}, []);

return (
    <div>
        <video controls style={{ height: 500, width: 500 }} autoPlay ref={userStream} />
    </div>
);

Python代码--

无法弄清楚如何处理从前端接收到的数据

from fastapi import FastAPI, WebSocket  

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket, data_image):
print("Accepting Connection")
await websocket.accept()
print('Accepted')
while True:
    try:

        image_bytes = await websocket.receive_bytes()
        print('Image Received')
        nparr = np.frombuffer(image_bytes, np.uint8)
        img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)

        # Do something with the image here
        # ...
        # Send a response back (optional)
        _, buffer = cv2.imencode('.jpg', img)
        response_bytes = buffer.tobytes()
        
        await websocket.send_bytes(response_bytes)
    except:
        pass
        break
python reactjs websocket fastapi
1个回答
0
投票

我没有设置反应环境来测试它,但我在 vanilla js 和 fastAPI 中得到了一些工作。我认为 fastAPI 方面是正确的,但前端缺少一些东西。

定义

userStream.current.srcObject = stream;
后,我认为你应该显式调用
userStream.current.play()
来开始播放视频。

那么您应该在连接网络套接字之前创建一个媒体记录器。

const mediaRecorder = new MediaRecorder(userStream.current.srcObject);

然后我会将

socket.onopen = () => ...
替换为:

    mediaRecorder.ondataavailable = async function(event) {
    if (event.data.size > 0 && socket.readyState === WebSocket.OPEN) {
        socket.send(await event.data.arrayBuffer());
    }
};

mediaRecorder.start(1000); // Send data every 1000ms
© www.soinside.com 2019 - 2024. All rights reserved.