python - Choppy 通过 UDP 接收语音数据
问题描述
我正在尝试通过 UDP 套接字发送语音数据,但是客户端接收到的语音数据断断续续。
server.py
目前,我正在client.py
同一台机器上运行。也许这可能是问题所在?另一种可能性是正在发送语音数据的短数据包,然后它播放得足够快以至于它会在短时间内结束。这也可能是硬件问题(我目前使用的是 2015 Macbook Pro)。
我已经在 TCP 中实现了这个程序,它完美地工作。但是,该程序的主要目的是处理大量客户。
我将尝试在不同的机器上运行这些脚本,看看它是否有效。期望的结果是以流畅的方式播放接收到的语音数据,而不是以断断续续的形式播放音频。
服务器.py
import socket
import pyaudio
import threading
from os import system
system('clear')
# Socket
host = socket.gethostbyname(socket.gethostname())
port = 6000
buffer = 2048
clients = []
# Audio
audio = pyaudio.PyAudio()
chunk = int(1024 * 4)
def client_listener():
while True:
data, address = host_socket.recvfrom(buffer)
if address not in clients:
print(f'New client: {address[0]}:{address[1]}')
clients.append(address)
print(clients)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as host_socket:
try:
host_socket.bind((host, port))
print(f'Server hosted at {host}:{port}\n')
print('Starting listener thread...')
listener_thread = threading.Thread(target=client_listener)
listener_thread.daemon = True
listener_thread.start()
print('Listener thread started!')
print('Initiating microphone...')
stream = audio.open(format=pyaudio.paInt16,
channels=1,
rate=44100,
input=True,
frames_per_buffer=chunk)
print('Recording!')
while True:
voice_data = stream.read(chunk, exception_on_overflow=False)
for client in clients:
host_socket.sendto(voice_data, client)
except socket.error as error:
print(str(error))
stream.close()
host_socket.close()
except KeyboardInterrupt:
stream.close()
host_socket.close()
finally:
stream.close()
host_socket.close()
客户端.py
import socket
import pyaudio
from os import system
# Socket
host = socket.gethostbyname(socket.gethostname())
port = 6000
system('clear')
# Audio
audio = pyaudio.PyAudio()
chunk = int(1024 * 4)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as client_socket:
try:
client_socket.sendto(' '.encode('utf-8'), (host, port))
stream = audio.open(format=pyaudio.paInt16,
channels=1,
rate=44100,
output=True,
frames_per_buffer=chunk)
while True:
voice_data = client_socket.recv(chunk)
print(voice_data)
stream.write(voice_data)
except socket.error as error:
print(str(error))
stream.close()
client_socket.close()
except KeyboardInterrupt:
stream.close()
client_socket.close()
finally:
stream.close()
client_socket.close()
解决方案
从网络的角度来看,我可以理解为什么 TCP 可以在 UDP 上完美运行。传输控制协议是一种纠错协议 - 也称为无损协议 - 并跟踪正在发送的内容以确定错误。如果发送的数据由于某种原因不完整,它会要求重新发送。用户数据报协议不是纠错和更多的流式传输 - 一个接一个。我不知道python,但是我建议如果您创建自己的纠错方法,那么如果您要使用UDP,它将获得与TCP相同的效果。类似于 MD5 检查的东西,接收者会知道“这个信息包是完整的”。
推荐阅读
- javascript - 使用循环的方法,编写程序打印9到N的表格
- amazon-web-services - 使用 AWS API Gateway 和 Lambda 的地理定位服务
- jsp - 带有“%=”标记的 VScode eslint 解析器错误
- sql - 希望显示最新的日期时间列
- msal.js - 服务器端渲染失败:错误 ReferenceError:未定义窗口
- java - 有没有办法使用 appium 将 VPN 信息添加到 aws devicefarm 设备池中的设备?
- c - 向主函数声明局部变量
- php - 不能在每个循环内设置变量数据
- javascript - 如何为垂直线提供动态高度
- javascript - 从 Node/Express 服务器在 React 中播放音频数据