使用 python 套接字流式传输视频并发送响应
stream video and send response using python sockets
我修改了 https://picamera.readthedocs.io/en/latest/recipes2.html#rapid-capture-and-streaming 的 picamera 脚本,以便能够将视频从我的树莓派流式传输到我的计算机,同时将命令从计算机发送到树莓派。
我的客户端代码如下所示:
while True:
stream.seek(0)
stream.truncate()
camera.capture(stream, 'jpeg', use_video_port=True)
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
print(returnmessage)
if returnmessage:
if returnmessage == 1:
#do something
else:
#do something else
和我的服务器代码:
while True:
image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
if not image_len:
break
image_stream = io.BytesIO()
image_stream.write(connection.read(image_len))
image_stream.seek(0)
data = np.frombuffer(image_stream.getvalue(), dtype=np.uint8)
image = cv2.imdecode(data, cv2.IMREAD_COLOR)
cv2.imshow('stream',image)
key = cv2.waitKey(1)
if key != -1:
if key == ord("g"):
print("pressed g")
connection.write(struct.pack('<L', 1))
connection.flush()
elif key == ord("h"):
print("pressed a")
connection.write(struct.pack('<L', 2))
connection.flush()
else:
connection.write(struct.pack('<L', 0))
connection.flush()
这行得通,但感觉不对,有时真的很慢。
根据流式 fps,我不必在每帧之后发送命令,因此等待响应并不总是必要的,但会降低流式 fps。
我该如何解决这个问题?我应该在每一侧打开另一个线程和另一个套接字来响应吗?
您可以将客户端套接字设置为非阻塞。
这样,当您尝试读取时 - 套接字将不会等待来自服务器的命令。
如果没有收到命令,connection.read
将立即 return。
为此,请致电 connection.setblocking(False)
。
出于我的目的,我发现将以下内容添加到客户端脚本似乎可以完成工作
reader, _, _ = select.select([connection], [], [], 0)
if reader:
returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
谢谢你的回答。
我修改了 https://picamera.readthedocs.io/en/latest/recipes2.html#rapid-capture-and-streaming 的 picamera 脚本,以便能够将视频从我的树莓派流式传输到我的计算机,同时将命令从计算机发送到树莓派。
我的客户端代码如下所示:
while True:
stream.seek(0)
stream.truncate()
camera.capture(stream, 'jpeg', use_video_port=True)
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
print(returnmessage)
if returnmessage:
if returnmessage == 1:
#do something
else:
#do something else
和我的服务器代码:
while True:
image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
if not image_len:
break
image_stream = io.BytesIO()
image_stream.write(connection.read(image_len))
image_stream.seek(0)
data = np.frombuffer(image_stream.getvalue(), dtype=np.uint8)
image = cv2.imdecode(data, cv2.IMREAD_COLOR)
cv2.imshow('stream',image)
key = cv2.waitKey(1)
if key != -1:
if key == ord("g"):
print("pressed g")
connection.write(struct.pack('<L', 1))
connection.flush()
elif key == ord("h"):
print("pressed a")
connection.write(struct.pack('<L', 2))
connection.flush()
else:
connection.write(struct.pack('<L', 0))
connection.flush()
这行得通,但感觉不对,有时真的很慢。 根据流式 fps,我不必在每帧之后发送命令,因此等待响应并不总是必要的,但会降低流式 fps。
我该如何解决这个问题?我应该在每一侧打开另一个线程和另一个套接字来响应吗?
您可以将客户端套接字设置为非阻塞。
这样,当您尝试读取时 - 套接字将不会等待来自服务器的命令。
如果没有收到命令,connection.read
将立即 return。
为此,请致电 connection.setblocking(False)
。
出于我的目的,我发现将以下内容添加到客户端脚本似乎可以完成工作
reader, _, _ = select.select([connection], [], [], 0)
if reader:
returnmessage = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0]
谢谢你的回答。