audio.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # -*- coding: utf-8 -*-
  2. from socket import *
  3. import threading
  4. import pyaudio
  5. import struct
  6. import pickle
  7. CHUNK = 1024
  8. FORMAT = pyaudio.paInt16
  9. CHANNELS = 2
  10. RATE = 44100
  11. RECORD_SECONDS = 0.5
  12. class Audio_Receive(threading.Thread):
  13. def __init__(self, HOST, PORT):
  14. threading.Thread.__init__(self)
  15. self.setDaemon(True)
  16. self.ADDR = (HOST, PORT)
  17. self.sock = socket(AF_INET, SOCK_STREAM)
  18. self.p = pyaudio.PyAudio()
  19. self.stream = None
  20. def __del__(self):
  21. self.sock.close()
  22. if self.stream is not None:
  23. self.stream.stop_stream()
  24. self.stream.close()
  25. self.p.terminate()
  26. def run(self):
  27. self.sock.connect_ex(self.ADDR)
  28. print("audio client connected...")
  29. data = "".encode("utf-8")
  30. payload_size = struct.calcsize("L")
  31. try:
  32. self.stream = self.p.open(format=FORMAT,
  33. channels=CHANNELS,
  34. rate=RATE,
  35. output=True,
  36. frames_per_buffer=CHUNK
  37. )
  38. while True:
  39. try:
  40. if len(data) < payload_size:
  41. data += self.sock.recv(81920)
  42. packed_size = data[:payload_size]
  43. data = data[payload_size:]
  44. msg_size = struct.unpack("L", packed_size)[0]
  45. if len(data) < msg_size:
  46. data += self.sock.recv(81920)
  47. frame_data = data[:msg_size]
  48. data = data[msg_size:]
  49. frames = pickle.loads(frame_data)
  50. for frame in frames:
  51. self.stream.write(frame, CHUNK)
  52. except:
  53. print('Audio data error')
  54. break
  55. except:
  56. self.sock.close()
  57. print('output device error,socket close')
  58. class Audio_Send(threading.Thread):
  59. def __init__(self, HOST, PORT):
  60. threading.Thread.__init__(self)
  61. self.setDaemon(True)
  62. self.ADDR = (HOST, PORT)
  63. self.sock = socket(AF_INET, SOCK_STREAM)
  64. self.p = pyaudio.PyAudio()
  65. self.stream = None
  66. def __del__(self):
  67. self.sock.close()
  68. if self.stream is not None:
  69. self.stream.stop_stream()
  70. self.stream.close()
  71. self.p.terminate()
  72. def run(self):
  73. self.sock.connect_ex(self.ADDR)
  74. print("audio_send connected...")
  75. try:
  76. self.stream = self.p.open(format=FORMAT,
  77. channels=CHANNELS,
  78. rate=RATE,
  79. input=True,
  80. frames_per_buffer=CHUNK)
  81. while self.stream.is_active():
  82. frames = []
  83. for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
  84. data = self.stream.read(CHUNK)
  85. frames.append(data)
  86. senddata = pickle.dumps(frames)
  87. try:
  88. self.sock.sendall(struct.pack(
  89. "L", len(senddata)) + senddata)
  90. except IOError:
  91. print('device data error')
  92. break
  93. except:
  94. self.sock.close()
  95. print('input device error, audio_send socket close')