|
|
@@ -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')
|