python 基于 websocket 的简单将视频推流到网页

avatar
作者
筋斗云
阅读量:2

本来有一台设备是要搞成无线的形式的,设备的摄像头的数据可以在一台局域网连接的平板上查看,因为试着使用 RTMP 推流,感觉延时太大了,而 Webrtc 感觉有太麻烦了,所以一开始看到这篇文章使用 UDP 协议进行推流,感觉挺有趣的。

但是因为我们要最后显示在 web 端,但是 web 使用 websocket,所以就使用 websocket 来进行推流了。

在这里插入图片描述
大体的架构图如上,带有摄像头的设备起一个 websocket server 的 python 服务,然后一个 html 的页面和这个服务器进行 websocket 连接,然后服务器就不断地推送帧图像的字节流给 web 客户端,在 html 页面就可以看到 websocket 服务器的摄像头的视频了。

  1. 在带摄像头的设备上启动这段 python 代码,作为 websocket 服务器。
import asyncio   import cv2   import websockets   import numpy as np      async def camera_stream(websocket, path):       cap = cv2.VideoCapture(0)         try:           while True:               ret, frame = cap.read()               if not ret:                   break                  buffer = cv2.imencode('.jpg', frame)[1]               await websocket.send(buffer.tobytes())               await asyncio.sleep(0.05)       finally:           cap.release()      start_server = websockets.serve(camera_stream, "0.0.0.0", 8080)      asyncio.get_event_loop().run_until_complete(start_server)   asyncio.get_event_loop().run_forever() 
  1. 在另外一个设备新建一个 html 文件,并打开
<!DOCTYPE html>   <html lang="en">   <head>       <meta charset="UTF-8">       <meta name="viewport" content="width=device-width, initial-scale=1.0">       <title>WebSocket Image Receiver</title>       <style>           #imageContainer {               display: flex;               flex-direction: column;               align-items: center;               justify-content: center;               height: 100vh;           }           img {               max-width: 100%;               max-height: 90vh;           }       </style>   </head>   <body>       <div id="imageContainer">           <img id="imageDisplay" src="#" alt="Received Image">       </div>       <script>           const socket = new WebSocket('ws://0.0.0.0:8080');           const imageElement = document.getElementById('imageDisplay');              socket.onopen = function(event) {               console.log('Connected to the WebSocket server.');           };              socket.onmessage = function(event) {               const imgBlob = new Blob([event.data], { type: 'image/jpeg' });               const imgUrl = URL.createObjectURL(imgBlob);               imageElement.src = imgUrl;           };              socket.onerror = function(error) {               console.error('WebSocket Error:', error);           };              socket.onclose = function(event) {               console.log('Disconnected from the WebSocket server.');           };       </script>   </body>   </html> 

如果是在同一台机子上跑的话,就不需要换 ip 地址,不然则需要查询 websocket 服务器的 ip 地址,并进行替换。

  1. 就可以在浏览器的网页中,看到设备传过来的视频流了。
    在这里插入图片描述
    延时性低,代码也比较简单,当然还有很多可以改进的地方。

参考文章:

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!