Python读视频流发送给前端H5呈现-websocket实现方法

  • Post author:
  • Post category:python


今天一个同事用Python做了一个关于机器视觉的处理,他希望处理的视频结果能够在H5页面上实时呈现出来,方便客户通过浏览器查看。折腾了一天终于搞定,现总结方法如下:



需求

Python读视频流进行处理,处理结果呈现在H5网页上,要求延时不能大于0.5秒。



分析

Python处理每一帧的图片,处理好以后发送到前端呈现,所以前端最好使用canvas或img标签呈现图片,通过实时更改canvas或img的图片可以达到视频呈现的效果。通过分析,我们决定使用图片的base64编码作为发送的图片数据,所以最终选择了img标签实现视频呈现。

实时显示图片使用轮询效率太低,我们选择使用node.js搭建WebSocket服务器,Python和JS与WebSocket服务器进行通信实现功能。



步骤



WebSocket服务器

使用node.js实现,需要安装ws(此处有坑,可以看看网上关于node.js中ws的安装方法)。

server.js内容如下:

let WebSocketServer = require('ws').Server,
    wss = new WebSocketServer({ port: 8188 });

wss.on('connection', function (ws) {
    console.log('客户端已连接');
    ws.on('message', function (message) {
        wss.clients.forEach(function each(client) {
            client.send(message);
        });
        console.log(message.length);
    });
});

需要注意的是:

wss.clients.forEach(function each(client) {
            client.send(message);
        });

这里需要添加一个广播,网上很多代码都没有写广播,有了广播Python端和JS端就可以监听当前socket服务器中的新消息了。



python端代码

python端代码如下:

import asyncio
import websockets
import base64
from cv2 import cv2
import numpy as np

capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if not capture.isOpened():
    print('quit')
    quit()
ret, frame = capture.read()
encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),95]

# 向服务器端实时发送视频截图
async def send_msg(websocket):
    global ret,frame
    while ret:
        #time.sleep(2)
        result, imgencode = cv2.imencode('.jpg', frame, encode_param)
        data = np.array(imgencode)
        img = data.tostring()

        # base64编码传输
        img = base64.b64encode(img).decode()
        await websocket.send("img=sq=data:image/jpeg;base64,"+img)
        await websocket.send("a1=sq="+repr(np.random.randn(7).tolist()))

        ret, frame = capture.read()

# 客户端主逻辑
async def main_logic():
    async with websockets.connect('ws://127.0.0.1:8188') as websocket:
        await send_msg(websocket)

asyncio.get_event_loop().run_until_complete(main_logic())

通过上面的代码我们可以实现实时视频数据往socket服务器推送。



H5网页代码

H5页面中代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <img id="resImg" src="" />
</div>
<script src="js/jquery-3.3.1.min.js" ></script>
<script>
        let ws = new WebSocket("ws://127.0.0.1:8188/");
        ws.onopen = function(evt) {
            console.log("Connection open ...");
            ws.send("Hello WebSockets!");
        };

        ws.onmessage = function(evt) {
            $("#resImg").attr("src",evt.data);
            console.log( "Received Message: " + evt.data);
           // ws.close();
        };

        ws.onclose = function(evt) {
            console.log("Connection closed.");
        };


</script>
</body>
</html>

最后我们通过node.js启动server.js

node server.js

打开h5页面就可以查看python推送过来的视频流了,非常流畅。从目前效果看无论是延时还是帧频都完全可以满足要求。



版权声明:本文为zhuzheqing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。