python - 从服务器流式传输视频
问题描述
我有一个加载视频的服务器和一个接收和显示视频的客户端。我是 python 新手。加载视频并将其发送到客户端/接收器的服务器代码。
server.py
import cv2
import socket
UDP_IP = "localhost"
UDP_PORT = 5005
cap = cv2.VideoCapture('D:\\testVideo.mp4')
while(True):
ret, frame = cap.read()
cv2.imshow('frame',frame)
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
d = frame.flatten ()
s = d.tostring ()
for i in range(20):
sock.sendto (s[i*46080:(i+1)*46080],(UDP_IP, UDP_PORT))
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
接收方代码
import socket
import numpy
import cv2
UDP_IP = "localhost"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind ((UDP_IP, UDP_PORT))
s=""
while True:
data, addr = sock.recvfrom(46080)
s += data
if len(s) == (46080*20):
frame = numpy.fromstring (s,dtype=numpy.uint8)
frame = frame.reshape (480,640,3)
cv2.imshow('frame',frame)
s=""
if cv2.waitKey(1) & 0xFF == ord ('q'):
break
我在“s += data”中遇到错误- TypeError: must be str, not bytes。我的追加有问题吗?我的方法正确吗?
解决方案
您的问题是它s
是一个字符串并+
连接字符串,但data
它是byte()
(或者甚至可能bytearray
,还不确定)。编辑:它似乎只包含一个字节串b\xff\xff\xff
您可以做的是保留一个bytearray
-buffer,然后接收到该缓冲区,因为您似乎无论如何都限制了文件大小(如果您的本地(字符串)缓冲区是一定长度,则检查每次迭代)。使用最大大小,您只需分配它并读取多少数据。如果有更多,它只是被切断,如果它更少,其余的将被 NULL 填充。有点像这样:
# allocate 32 bytes as buffer
s = bytearray(32)
sock.recvmsg_into([s])
通过运行以下 Python 代码对此进行测试:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("localhost", 8080))
# reserve a buffer of 4 bytes
s = bytearray(4)
sock.recvmsg_into([s])
此时,套接字将阻塞并等待输入。从第二个终端运行:
echo "foobar" | nc -u 127.0.0.1 8080
您的 Python 脚本将继续执行并打印它收到的内容:
(4, [], 32, ('127.0.0.1', 56464))
>>> s
bytearray(b'foob')
如果您不想走那条路,我有一个解决方案来解决您最初的方法,即在无限循环中追加。我之前发布了一个附加到 a 的解决方案bytearray
,但由于类型不匹配,这不起作用。事实证明你甚至不需要bytearray
,因为这可以按预期工作:
s = bytes()
while True:
s += bytes(b'foobar')
if s == b'foobarfoobar':
print(s)
break
推荐阅读
- c++ - 多线程 - 同步值与互斥锁?
- c++ - 为什么互斥锁(std::mutex)很重?
- postgresql - 将现有 UTC 字段转换为 pst
- node.js - 节点 Lambda 超时 firebase-admin SDK
- openstreetmap - 如何使用 Open Street Maps API 从坐标中获取地址?
- javascript - 获取选中单选按钮的文本
- scala - 在 Spark 中对 RDD 进行排序
- yaml - 解析 k8s-geneva-redis-no-secty.yml 时出错:将 YAML 转换为 JSON 时出错:yaml:第 92 行:在此上下文中不允许映射值
- ms-access - Microsoft Access - 合并具有相同字段的多个表
- python - 如何将异步请求与底层套接字请求分开