先说下实现原理,如下图:
Python使用cv2拉取摄像头的视频帧,压缩、解码、编码等处理后将图片base64编码后通过websocket发送给服务端,服务端将此帧图片存下来,当有客户端请求图片数据时服务端不断地将图片帧发送给请求websocket客户端。客户端不断的刷新图片以达到视频播放的效果。
可以根据代码中quality参数设置图片的质量4流畅3高清2标清1超清,本人测试在1M带宽的网络环境可以达到1秒10帧、延迟低的效果只是画面效果不好。标清则需要大约5M带宽,高清大概需要10M带宽,超清需要20M带宽。
Python端代码如下:
#向服务端发送数据的线程
import cv2
import base64
import websocket
import threading
class SendThread (threading.Thread):
def __init__(self, video_url, ws_server_url, camera_id):
threading.Thread.__init__(self)
#"rtsp://admin:a1234567@192.168.8.11:554/h264/ch1/main/av_stream"
self._video_url = video_url
self._ws = None
self._ws_server_url = ws_server_url
self._capture = None
self._send = True
#视频播放质量4流畅3标清2高清1超清
self._quality = 4
self._camera_id = camera_id
def run(self):
websocket.enableTrace(False)
self._ws = websocket.WebSocketApp(self._ws_server_url,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close,
on_open=self.on_open)
self._ws.run_forever()
def send_frame(self):
self._capture = cv2.VideoCapture(self._video_url)
frame_width = int(self._capture.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(self._capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
while self._send:
ret, frame = self._capture.read()
if ret:
# 576,324
r = int(2 + self._quality * 0.5)
frame = cv2.resize(frame,(frame_width // r,frame_height // r))
#图片质量1-100
jpeg_quality = 100 - 10 * self._quality
img_param = [int(cv2.IMWRITE_JPEG_QUALITY), jpeg_quality]
# 转化
ret, frame = cv2.imencode('.jpg', frame, img_param)
if ret:
self._ws.send(base64.b64encode(frame).decode("utf-8"))
def on_message(self, message):
print(message)
def on_error(self, error):
print(error)
global send_thread_pool
del send_thread_pool[self._camera_id]
self._send = False
self._capture.release()
def on_close(self):
print("closed video send!")
global send_thread_pool
del send_thread_pool[self._camera_id]
self._send = False
self._capture.release()
def on_open(self):
print('连接媒体服务器成功!')
global send_thread_pool
send_thread_pool[self._camera_id] = self
self.send_frame()
def set_quality(self, quality):
self._quality = quality
web页面代码如下:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>视频播放</title>
<script type="text/javascript">
var wsVideo = new WebSocket("ws://video/read/e064213cf7ba449cbc2904c95fab0);
wsVideo.onmessage = function(evt){
document.getElementById("img1").src = "data:image/jpeg;base64," + evt.data;
}
</script>
</head>
<body>
<div id="sse">
<img id="img1" width="100%" height="100%">
</div>
</body>
</html>