Browse Source

Signed-off-by: Caner <5658514@qq.com>

Caner 4 years ago
parent
commit
27db5844e3

BIN
132.mp4


+ 104 - 0
PlanA/client/audio.py

@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import pyaudio
+import struct
+import pickle
+
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+RECORD_SECONDS = 0.5
+
+
+class Audio_Receive(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      output=True,
+                                      frames_per_buffer=CHUNK
+                                      )
+            while True:
+                try:
+                    if len(data) < payload_size:
+                        data += self.sock.recv(81920)
+                    packed_size = data[:payload_size]
+                    data = data[payload_size:]
+                    msg_size = struct.unpack("L", packed_size)[0]
+                    if len(data) < msg_size:
+                        data += self.sock.recv(81920)
+                    frame_data = data[:msg_size]
+                    data = data[msg_size:]
+                    frames = pickle.loads(frame_data)
+                    for frame in frames:
+                        self.stream.write(frame, CHUNK)
+                except:
+                    print('Audio data error')
+                    break
+        except:
+            self.sock.close()
+            print('output device error,socket close')
+
+
+class Audio_Send(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio_send  connected...")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      input=True,
+                                      frames_per_buffer=CHUNK)
+            while self.stream.is_active():
+                frames = []
+                for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
+                    data = self.stream.read(CHUNK)
+                    frames.append(data)
+                senddata = pickle.dumps(frames)
+                try:
+                    self.sock.sendall(struct.pack(
+                        "L", len(senddata)) + senddata)
+                except IOError:
+                    print('device data error')
+                    break
+        except:
+            self.sock.close()
+            print('input device error,audio_send socket close')

+ 29 - 0
PlanA/client/main.py

@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+import time
+import sys
+from video import Video_Client
+from audio import Audio_Receive, Audio_Send
+
+
+# HOST = '172.16.102.9'
+# PORT = 10087
+HOST = '81.70.80.219'
+PORT = 49800
+
+if __name__ == '__main__':
+    # 视频接收
+    vclient = Video_Client(HOST, PORT)
+    vclient.start()
+    # 语音接收
+    aReceive = Audio_Receive(HOST, PORT+1)
+    aReceive.start()
+    # 语音发送
+    aSend = Audio_Send(HOST, PORT+2)
+    aSend.start()
+
+    while True:
+        time.sleep(1)
+        if not vclient.is_alive():
+            print("Client close")
+            sys.exit(0)
+        pass

+ 62 - 0
PlanA/client/video.py

@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class Video_Client(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        print('video clinet start')
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+
+    def __del__(self):
+        self.sock.close()
+        try:
+            cv2.destroyAllWindows()
+        except:
+            pass
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("video client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        cv2.namedWindow('Remote', cv2.WINDOW_NORMAL)
+        while True:
+            try:
+                while len(data) < payload_size:
+                    data += self.sock.recv(81920)
+                packed_size = data[:payload_size]
+                data = data[payload_size:]
+                msg_size = struct.unpack("L", packed_size)[0]
+                while len(data) < msg_size:
+                    data += self.sock.recv(81920)
+                zframe_data = data[:msg_size]
+                data = data[msg_size:]
+                frame_data = zlib.decompress(zframe_data)
+                frame = pickle.loads(frame_data)
+                try:
+                    cv2.imshow('Remote', frame)
+                    key = cv2.waitKey(10)
+                    if key == ord('q'):
+                        print('client exit')
+                        cv2.destroyAllWindows()
+                        self.sock.close()
+                except:
+                    print('video server error')
+                    cv2.destroyAllWindows()
+                    self.sock.close()
+            except:
+                self.sock.close()
+                try:
+                    cv2.destroyAllWindows()
+                except:
+                    pass
+                print('server close')
+                break

+ 4 - 0
PlanA/readme.md

@@ -0,0 +1,4 @@
+1. 此方案采用服务端转发
+2. 客户端各自发送接收
+3. 增加网速,电量提示
+4. 增加音频发送,接收

+ 104 - 0
PlanA/send_client/audio.py

@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import pyaudio
+import struct
+import pickle
+
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+RECORD_SECONDS = 0.5
+
+
+class Audio_Receive(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      output=True,
+                                      frames_per_buffer=CHUNK
+                                      )
+            while True:
+                try:
+                    if len(data) < payload_size:
+                        data += self.sock.recv(81920)
+                    packed_size = data[:payload_size]
+                    data = data[payload_size:]
+                    msg_size = struct.unpack("L", packed_size)[0]
+                    if len(data) < msg_size:
+                        data += self.sock.recv(81920)
+                    frame_data = data[:msg_size]
+                    data = data[msg_size:]
+                    frames = pickle.loads(frame_data)
+                    for frame in frames:
+                        self.stream.write(frame, CHUNK)
+                except:
+                    print('Audio data error')
+                    break
+        except:
+            self.sock.close()
+            print('output device error,socket close')
+
+
+class Audio_Send(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio_send  connected...")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      input=True,
+                                      frames_per_buffer=CHUNK)
+            while self.stream.is_active():
+                frames = []
+                for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
+                    data = self.stream.read(CHUNK)
+                    frames.append(data)
+                senddata = pickle.dumps(frames)
+                try:
+                    self.sock.sendall(struct.pack(
+                        "L", len(senddata)) + senddata)
+                except IOError:
+                    print('device data error')
+                    break
+        except:
+            self.sock.close()
+            print('input device error, audio_send socket close')

+ 31 - 0
PlanA/send_client/main.py

@@ -0,0 +1,31 @@
+import time
+import sys
+from video import Send_Video_Client
+from audio import Audio_Receive, Audio_Send
+# FX 压缩率
+HOST = '172.16.102.9'
+PORT = 10087
+# SPD 速率 1000 * SPD = FPS
+# HOST = '81.70.80.219'
+# PORT = 49900
+FX = 0.5
+SPD = 0.125
+
+
+if __name__ == '__main__':
+    # 视频发送
+    vserver = Send_Video_Client(HOST, PORT, FX, SPD)
+    vserver.start()
+    # 语音接收
+    aReceive = Audio_Receive(HOST, PORT+1)
+    aReceive.start()
+    # 语音发送
+    aSend = Audio_Send(HOST, PORT+2)
+    aSend.start()
+
+    while True:
+        time.sleep(1)
+        if not vserver.is_alive():
+            print("Video server close")
+            sys.exit(0)
+        pass

+ 71 - 0
PlanA/send_client/video.py

@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+import cv2
+import struct
+import pickle
+import zlib
+import time
+import threading
+from socket import *
+import psutil
+from pythonping import ping
+
+
+class Send_Video_Client(threading.Thread):
+    # 只发送视频
+    def __init__(self, HOST, PORT, FX, SPD):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.fx = FX  # 压缩率
+        self.spd = SPD  # 速率
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.cap = cv2.VideoCapture(
+            'C:/Users/Caner/Desktop/ichat0.2/Video_Socket/132.mp4')
+        self.font = cv2.FONT_HERSHEY_SIMPLEX
+
+    def __del__(self):
+        self.sock.close()
+        self.cap.release()
+        pass
+
+    def run(self):
+        # 连接socket
+        print('start connecting socket server...')
+        while True:
+            try:
+                self.sock.connect_ex(self.ADDR)
+                break
+            except:
+                print('restart connecting socket server...')
+                time.sleep(3)
+                continue
+
+        # 发送视频
+        while self.cap.isOpened():
+            # 增加电量
+            battery = psutil.sensors_battery()
+            percent = str(battery)
+            if percent == 'None':
+                percent = str(100)
+            # 增加网速
+            # sent_before = psutil.net_io_counters().bytes_sent  # 已发送的流量
+            # recv_before = psutil.net_io_counters().bytes_recv  # 已接收的流量
+            # 增加网络测试
+            res = ping('www.baidu.com')
+            delay = str(res.rtt_avg_ms)
+            time.sleep(self.spd)
+            res, frame = self.cap.read()
+            # sent_now = psutil.net_io_counters().bytes_sent
+            # net = round(((sent_now - sent_before) / 1024), 2)  # 算出差值
+            arr = [delay, percent]
+            text = "delay: {0[0]}ms  power: {0[1]}%  ".format(arr)
+            if res:
+                cv2.putText(frame, text, (0, 30), self.font, 1, (0, 0, 255), 2)
+                sframe = cv2.resize(frame, (0, 0), fx=self.fx, fy=self.fx)
+                data = pickle.dumps(sframe)
+                zdata = zlib.compress(data, zlib.Z_BEST_COMPRESSION)
+                try:
+                    self.sock.sendall(struct.pack("L", len(zdata)) + zdata)
+                except:
+                    print('client close:')
+                    break

+ 43 - 0
PlanA/send_server/AppendClient.py

@@ -0,0 +1,43 @@
+import threading
+
+
+class AppendClient(threading.Thread):
+    def __init__(self, USERLIST, USER, BUFSIZE, ADDR):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.USERLIST = USERLIST
+        self.USER = USER
+        self.BUFSIZE = BUFSIZE
+        self.ADDR = ADDR
+        pass
+
+    def __del__(self):
+        if self.USER in self.USERLIST:
+            self.USERLIST.remove(self.USER)
+        self.USER.close()
+        pass
+
+    def run(self):
+        # 添加用户
+        self.USERLIST.append(self.USER)
+        # 接收用户信息
+        while True:
+            try:
+                msg = self.USER.recv(self.BUFSIZE)
+                if not msg:
+                    self.USERLIST.remove(self.USER)
+                    self.USER.close()
+                    print('client exit 一,UserListLenght:', len(self.USERLIST))
+                    break
+                # 去除自己,客户端大于1才转发
+                if len(self.USERLIST) > 1:
+                    for c in self.USERLIST:
+                        if c != self.USER:
+                            print('转发')
+                            c.sendall(msg)
+            except:
+                self.USERLIST.remove(self.USER)
+                self.USER.close()
+                print('client exit 二,UserListLenght:', len(self.USERLIST))
+                break
+        pass

+ 38 - 0
PlanA/send_server/send_main.py

@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+from socket import *
+from time import ctime
+from AppendClient import AppendClient
+# 服务配置
+HOST = '172.16.102.9'
+PORT = 10087
+# HOST = '127.0.0.1'
+# PORT = 49900
+BUFSIZE = 81920
+ADDR = (HOST, PORT)
+userList = []
+MAXCLIENT = 2
+
+
+def loopServer(tcpSrvSock):
+    # 服务监听
+    global userList, MAXCLIENT
+    while True:
+        print('Waiting For Client Connection ...', ctime())
+        tcpCliSock, addr = tcpSrvSock.accept()  # 会阻塞
+        print('NewUser', addr, ctime())
+        print('UserListLenght:', len(userList))
+        # 增加线程
+        if tcpCliSock not in userList and len(userList) < MAXCLIENT:
+            newClinet = AppendClient(userList, tcpCliSock, BUFSIZE, addr)
+            newClinet.start()
+        else:
+            # 不允许连接
+            print('不允许连接')
+            tcpCliSock.close()
+
+
+if __name__ == '__main__':
+    tcpSrvSock = socket(AF_INET, SOCK_STREAM)
+    tcpSrvSock.bind(ADDR)
+    tcpSrvSock.listen(1)
+    loopServer(tcpSrvSock)

+ 104 - 0
PlanB/client/audio.py

@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import pyaudio
+import struct
+import pickle
+
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+RECORD_SECONDS = 0.5
+
+
+class Audio_Receive(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      output=True,
+                                      frames_per_buffer=CHUNK
+                                      )
+            while True:
+                try:
+                    if len(data) < payload_size:
+                        data += self.sock.recv(81920)
+                    packed_size = data[:payload_size]
+                    data = data[payload_size:]
+                    msg_size = struct.unpack("L", packed_size)[0]
+                    if len(data) < msg_size:
+                        data += self.sock.recv(81920)
+                    frame_data = data[:msg_size]
+                    data = data[msg_size:]
+                    frames = pickle.loads(frame_data)
+                    for frame in frames:
+                        self.stream.write(frame, CHUNK)
+                except:
+                    print('Audio data error')
+                    break
+        except:
+            self.sock.close()
+            print('output device error,socket close')
+
+
+class Audio_Send(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio_send  connected...")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      input=True,
+                                      frames_per_buffer=CHUNK)
+            while self.stream.is_active():
+                frames = []
+                for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
+                    data = self.stream.read(CHUNK)
+                    frames.append(data)
+                senddata = pickle.dumps(frames)
+                try:
+                    self.sock.sendall(struct.pack(
+                        "L", len(senddata)) + senddata)
+                except IOError:
+                    print('device data error')
+                    break
+        except:
+            self.sock.close()
+            print('input device error,audio_send socket close')

+ 28 - 0
PlanB/client/main.py

@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+import time
+import sys
+from video import Video_Client
+from audio import Audio_Receive, Audio_Send
+
+
+HOST = '172.16.102.9'
+PORT = 10087
+
+
+if __name__ == '__main__':
+    # 视频接收
+    vclient = Video_Client(HOST, PORT)
+    vclient.start()
+    # 语音接收
+    aReceive = Audio_Receive(HOST, PORT+1)
+    aReceive.start()
+    # 语音发送
+    aSend = Audio_Send(HOST, PORT+2)
+    aSend.start()
+
+    while True:
+        time.sleep(1)
+        if not vclient.is_alive():
+            print("Client close")
+            sys.exit(0)
+        pass

+ 62 - 0
PlanB/client/video.py

@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class Video_Client(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        print('video clinet start')
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+
+    def __del__(self):
+        self.sock.close()
+        try:
+            cv2.destroyAllWindows()
+        except:
+            pass
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("video client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        cv2.namedWindow('Remote', cv2.WINDOW_NORMAL)
+        while True:
+            try:
+                while len(data) < payload_size:
+                    data += self.sock.recv(81920)
+                packed_size = data[:payload_size]
+                data = data[payload_size:]
+                msg_size = struct.unpack("L", packed_size)[0]
+                while len(data) < msg_size:
+                    data += self.sock.recv(81920)
+                zframe_data = data[:msg_size]
+                data = data[msg_size:]
+                frame_data = zlib.decompress(zframe_data)
+                frame = pickle.loads(frame_data)
+                try:
+                    cv2.imshow('Remote', frame)
+                    key = cv2.waitKey(10)
+                    if key == ord('q'):
+                        print('client exit')
+                        cv2.destroyAllWindows()
+                        self.sock.close()
+                except:
+                    print('video server error')
+                    cv2.destroyAllWindows()
+                    self.sock.close()
+            except:
+                self.sock.close()
+                try:
+                    cv2.destroyAllWindows()
+                except:
+                    pass
+                print('server close')
+                break

+ 1 - 0
PlanB/readme.md

@@ -0,0 +1 @@
+1. 此方案采用树莓派采集视频进行转发机制

+ 40 - 0
PlanB/server_v2/main.py

@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+from socket import *
+from time import ctime
+from video import Video_Server
+# 服务配置
+HOST = '172.16.102.9'
+PORT = 10087
+
+BUFSIZE = 81920
+ADDR = (HOST, PORT)
+userList = []
+MAXCLIENT = 1
+FX = 0.5
+SPD = 0.125
+
+
+def loopServer(tcpSrvSock):
+    # 服务监听
+    global userList, MAXCLIENT
+    while True:
+        print('Waiting For Client Connection ...', ctime())
+        tcpCliSock, addr = tcpSrvSock.accept()  # 会阻塞
+        print('NewUser', addr, ctime())
+        print('UserListLenght:', len(userList))
+        # 增加线程
+        if tcpCliSock not in userList and len(userList) < MAXCLIENT:
+            newClinet = Video_Server(
+                userList, tcpCliSock, BUFSIZE, addr, SPD, FX)
+            newClinet.start()
+        else:
+            # 不允许连接
+            print('不允许连接')
+            tcpCliSock.close()
+
+
+if __name__ == '__main__':
+    tcpSrvSock = socket(AF_INET, SOCK_STREAM)
+    tcpSrvSock.bind(ADDR)
+    tcpSrvSock.listen(1)
+    loopServer(tcpSrvSock)

+ 50 - 0
PlanB/server_v2/video.py

@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import time
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class Video_Server(threading.Thread):
+    def __init__(self, USERLIST, USER, BUFSIZE, ADDR, SPD, FX):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.cap = cv2.VideoCapture(
+            'C:/Users/Caner/Desktop/ichat0.2/Video_Socket/132.mp4')
+        self.USERLIST = USERLIST
+        self.USER = USER
+        self.BUFSIZE = BUFSIZE
+        self.ADDR = ADDR
+        self.spd = SPD
+        self.fx = FX
+        pass
+
+    def __del__(self):
+        if self.USER in self.USERLIST:
+            self.USER.close()
+            self.USERLIST.remove(self.USER)
+        self.cap.release()
+        pass
+
+    def run(self):
+        # 添加用户
+        self.USERLIST.append(self.USER)
+        while self.cap.isOpened():
+            time.sleep(self.spd)
+            res, frame = self.cap.read()
+            if res:
+                sframe = cv2.resize(
+                    frame, (0, 0), fx=self.fx, fy=self.fx)
+                data = pickle.dumps(sframe)
+                zdata = zlib.compress(data, zlib.Z_BEST_COMPRESSION)
+                try:
+                    self.USER.sendall(struct.pack("L", len(zdata)) + zdata)
+                except:
+                    self.USER.close()
+                    self.USERLIST.remove(self.USER)
+                    self.cap.release()
+                    print('client close:', time.ctime(), len(self.USERLIST))
+                    break

+ 104 - 0
PlanC/client/audio.py

@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import pyaudio
+import struct
+import pickle
+
+CHUNK = 1024
+FORMAT = pyaudio.paInt16
+CHANNELS = 2
+RATE = 44100
+RECORD_SECONDS = 0.5
+
+
+class Audio_Receive(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      output=True,
+                                      frames_per_buffer=CHUNK
+                                      )
+            while True:
+                try:
+                    if len(data) < payload_size:
+                        data += self.sock.recv(81920)
+                    packed_size = data[:payload_size]
+                    data = data[payload_size:]
+                    msg_size = struct.unpack("L", packed_size)[0]
+                    if len(data) < msg_size:
+                        data += self.sock.recv(81920)
+                    frame_data = data[:msg_size]
+                    data = data[msg_size:]
+                    frames = pickle.loads(frame_data)
+                    for frame in frames:
+                        self.stream.write(frame, CHUNK)
+                except:
+                    print('Audio data error')
+                    break
+        except:
+            self.sock.close()
+            print('output device error,socket close')
+
+
+class Audio_Send(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.p = pyaudio.PyAudio()
+        self.stream = None
+
+    def __del__(self):
+        self.sock.close()
+        if self.stream is not None:
+            self.stream.stop_stream()
+            self.stream.close()
+        self.p.terminate()
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("audio_send  connected...")
+        try:
+            self.stream = self.p.open(format=FORMAT,
+                                      channels=CHANNELS,
+                                      rate=RATE,
+                                      input=True,
+                                      frames_per_buffer=CHUNK)
+            while self.stream.is_active():
+                frames = []
+                for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
+                    data = self.stream.read(CHUNK)
+                    frames.append(data)
+                senddata = pickle.dumps(frames)
+                try:
+                    self.sock.sendall(struct.pack(
+                        "L", len(senddata)) + senddata)
+                except IOError:
+                    print('device data error')
+                    break
+        except:
+            self.sock.close()
+            print('input device error,audio_send socket close')

+ 28 - 0
PlanC/client/main.py

@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+import time
+import sys
+from video import Video_Client
+from audio import Audio_Receive, Audio_Send
+
+
+HOST = '172.16.102.9'
+PORT = 10087
+
+
+if __name__ == '__main__':
+    # 视频接收
+    vclient = Video_Client(HOST, PORT)
+    vclient.start()
+    # 语音接收
+    aReceive = Audio_Receive(HOST, PORT+1)
+    aReceive.start()
+    # 语音发送
+    aSend = Audio_Send(HOST, PORT+2)
+    aSend.start()
+
+    while True:
+        time.sleep(1)
+        if not vclient.is_alive():
+            print("Client close")
+            sys.exit(0)
+        pass

+ 62 - 0
PlanC/client/video.py

@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from socket import *
+import threading
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class Video_Client(threading.Thread):
+    def __init__(self, HOST, PORT):
+        threading.Thread.__init__(self)
+        print('video clinet start')
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+
+    def __del__(self):
+        self.sock.close()
+        try:
+            cv2.destroyAllWindows()
+        except:
+            pass
+
+    def run(self):
+        self.sock.connect_ex(self.ADDR)
+        print("video client  connected...")
+        data = "".encode("utf-8")
+        payload_size = struct.calcsize("L")
+        cv2.namedWindow('Remote', cv2.WINDOW_NORMAL)
+        while True:
+            try:
+                while len(data) < payload_size:
+                    data += self.sock.recv(81920)
+                packed_size = data[:payload_size]
+                data = data[payload_size:]
+                msg_size = struct.unpack("L", packed_size)[0]
+                while len(data) < msg_size:
+                    data += self.sock.recv(81920)
+                zframe_data = data[:msg_size]
+                data = data[msg_size:]
+                frame_data = zlib.decompress(zframe_data)
+                frame = pickle.loads(frame_data)
+                try:
+                    cv2.imshow('Remote', frame)
+                    key = cv2.waitKey(10)
+                    if key == ord('q'):
+                        print('client exit')
+                        cv2.destroyAllWindows()
+                        self.sock.close()
+                except:
+                    print('video server error')
+                    cv2.destroyAllWindows()
+                    self.sock.close()
+            except:
+                self.sock.close()
+                try:
+                    cv2.destroyAllWindows()
+                except:
+                    pass
+                print('server close')
+                break

+ 1 - 0
PlanC/readme.md

@@ -0,0 +1 @@
+1. 此方案为服务端采集视频进行转发(初版)

+ 22 - 0
PlanC/server/main.py

@@ -0,0 +1,22 @@
+import sys
+import time
+from video import Video_Server
+# from audio import Audio_Client
+
+# FX分辨率
+HOST = '172.16.102.9'
+PORT = 10087
+FX = 0.4
+SPD = 0.1
+
+if __name__ == '__main__':
+    vserver = Video_Server(HOST, PORT, FX, SPD)
+    # aclient = Audio_Client(HOST, PORT+1)
+    vserver.start()
+    # aclient.start()
+    while True:
+        time.sleep(1)
+        if not vserver.is_alive():
+            print("Video server close")
+            sys.exit(0)
+        pass

+ 45 - 0
PlanC/server/video.py

@@ -0,0 +1,45 @@
+from socket import *
+import threading
+import time
+import cv2
+import struct
+import pickle
+import zlib
+
+
+class Video_Server(threading.Thread):
+    def __init__(self, HOST, PORT, FX, SPD):
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.ADDR = (HOST, PORT)
+        self.sock = socket(AF_INET, SOCK_STREAM)
+        self.sock.bind(self.ADDR)  # 套接字绑定的IP与端口
+        self.sock.listen(1)  # 开始TCP监听,监听1个请求
+        self.cap = cv2.VideoCapture(
+            'C:/Users/Caner/Desktop/ichat0.2/Video_Socket/132.mp4')
+        self.fx = FX  # 压缩率
+        self.spd = SPD  # 速率
+        pass
+
+    def __del__(self):
+        self.sock.close()
+        self.cap.release()
+        pass
+
+    def run(self):
+        while True:
+            print('wait NewClient connect...')
+            conn, addr = self.sock.accept()  # 会阻塞
+            print('client connected:', addr)
+            while self.cap.isOpened():
+                time.sleep(self.spd)
+                res, frame = self.cap.read()
+                if res:
+                    sframe = cv2.resize(frame, (0, 0), fx=self.fx, fy=self.fx)
+                    data = pickle.dumps(sframe)
+                    zdata = zlib.compress(data, zlib.Z_BEST_COMPRESSION)
+                    try:
+                        conn.sendall(struct.pack("L", len(zdata)) + zdata)
+                    except:
+                        print('client close:', addr)
+                        break