admin管理员组

文章数量:1794759

Python读视频流发送给前端H5呈现

Python读视频流发送给前端H5呈现

今天一个同事用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推送过来的视频流了,非常流畅。从目前效果看无论是延时还是帧频都完全可以满足要求。

本文标签: 发送给视频Python