我在python中使用套接字编写了两个系统之间的视频共享代码。我分叉了4个进程,每个进程执行以下任务:记录帧,发送记录的帧,接收帧,播放接收的帧。 这是我的代码:
import socket
import cv2
import time
from threading import Thread
from multiprocessing import Process, Queue
import sys
import pickle
import numpy as np
import zlib
HOST="192.168.43.42"
PORT=1060
MAX=65535
frames_record=Queue()
frames_play=Queue()
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#data_to_decomp=""
def record(frames_record):
cap = cv2.VideoCapture(0)
cap.set(3, 160)#reducing width
cap.set(4, 120)#reducing height
compressed_frame=""#frames to compress
while (cap.isOpened()):
ret, frame=cap.read()
print "HERE 1"
compressed_frame=zlib.compress(pickle.dumps(frame))+"end"
frames_record.put(compressed_frame)
compressed_frame=""
#if cv2.waitKey(0) & 0xFF == ord('q'):
# break
time.sleep(0.0001)
cap.release()
def send(sock, addr, frames_record):
while True:
if not frames_record.empty():
print "in send"
#print sys.getsizeof(frames_record[0])
#print len(frames_record[0])
#print frames_record[0]
sock.sendto((frames_record.get()), addr)
time.sleep(0.0001)
def play(frames_play):
print "in play"
while True:
if not frames_play.empty()>0:
print "in playing"
frame=frames_play.get()
cv2.imshow("chat", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(0.0001)
cv2.destroyAllWindows()
def recv_all(sock, frames_play):
print "in recv_all"
msg=""
while True:
while "end" not in msg:
print "in recv_all"
data, addr=sock.recvfrom(MAX)
msg+=data
index=msg.find("end")
decompressed_frame=zlib.decompress(msg[:index])#frames to decompress
frames_play.put(pickle.loads(decompressed_frame))
if not msg.endswith("end"):
msg=msg[index+3:]
else:
msg=""
time.sleep(0.0001)
if sys.argv[1] == "server":
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("", PORT))
t_recv=Process(target=recv_all, args=(s, frames_play,))
t_play=Process(target=play, args=(frames_play,))
#t_recv.setDaemon(True)
#t_play.setDaemon(True)
t_record=Process(target=record, args=(frames_record,))
t_send=Process(target=send, args=(s,(HOST, PORT), frames_record,))
#t_record.setDaemon(True)
#t_send.setDaemon(True)
t_record.start()
t_recv.start()
t_play.start()
t_send.start()
t_record.join()
t_send.join()
t_recv.join()
t_play.join()
s.close()
elif sys.argv[1] == "client":
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("", PORT))
#s.connect((HOST, PORT))
t_record=Process(target=record, args=(frames_record,))
t_send=Process(target=send, args=(s,(HOST, PORT), frames_record,))
#t_record.setDaemon(True)
#t_send.setDaemon(True)
t_recv=Process(target=recv_all, args=(s, frames_play,))
t_play=Process(target=play, args=(frames_play,))
#t_recv.setDaemon(True)
#t_play.setDaemon(True)
t_record.start()
t_send.start()
t_recv.start()
t_play.start()
t_recv.join()
t_play.join()
t_record.join()
t_send.join()
s.close()
else:
print "Error: Usage: python filename.py <server/client>"
当我在两个独立的系统上运行此代码时,我发现(使用print语句)大多数情况下程序在两个系统中都卡在t_record
和t_send
中。我无法理解为什么控件不会转移到其他两个进程(t_recv
和t_play
)。
PS:我也尝试过线程,它也没有用。两个系统上的视频都在第一帧上冻结,我不得不强制停止这个过程。