5
按理说500ms一个chunk,推理+播放延迟应该不会超过1-2秒吧,推理完成第1个chunk应该就会开始播放音频了,是gradio的问题吗?我的设备没有播放器,只能用webui播放音频,如果直接用pyaudio本地播放会不会没有这么高延迟?
按理说500ms一个chunk,推理+播放延迟应该不会超过1-2秒吧,推理完成第1个chunk应该就会开始播放音频了,是gradio的问题吗?我的设备没有播放器,只能用webui播放音频,如果直接用pyaudio本地播放会不会没有这么高延迟?
增大输出速度会引入爆音,可以调节InferCodeParams
的stream_speed
参数以查看效果。
流式首包1-2秒,设备没有播放器可以拿普通电脑作客户端播放声音,给远程有gpu的服务端请求流式获取声音数据
嗯嗯,我现在就是这样实现了,速度确实快了一些,但是刚播放时会有一段噪音,期间也会有电流音,请问这是什么情况呢
应该是写入不够快声音断断续续导致,开始播放时比较容易出现。最好是推理足够快(比播放快),而且客户端那边也要非阻塞的持续将声音数据写入播放器 可以在客户端实现一个持续获取网络数据的generator,播放器同时进行写入和播放。示例
import io
import threading
class Player:
def __init__(self,waittime_topause=600):
self.bio = io.BytesIO()
self.lock = threading.Lock()
self.seek_index = 0
self.waittime_topause=waittime_topause
self.finish=False
def _write(self,write_binary):
with self.lock:
self.bio.write(write_binary)
def _read(self,):
with self.lock:
self.bio.seek(self.seek_index)
read_binary = self.bio.read()
self.seek_index += len(read_binary)
return read_binary
def write(self,voice_generator):
self.finish = False
for audio_binary in voice_generator:
self._write(audio_binary)
self.finish=True
def play(self,waittime_tostart,auto_end=False):
self.end=False## force ending
import pyaudio
# 初始化PyAudio对象
p = pyaudio.PyAudio()
# 设置音频流参数
FORMAT = pyaudio.paInt16 # 16位深度
CHANNELS = 1 # 单声道
RATE = 24000 # 采样率
CHUNK = 1024 # 每块音频数据大小
# 打开输出流(扬声器)
stream_out = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True)
print("开始流式音频播放...")
import time
time.sleep(waittime_tostart)
wait_time = 0
while (self.bio.tell() > self.seek_index) | (
wait_time < self.waittime_topause
):
if self.bio.tell() > self.seek_index:
read_data = self._read()
stream_out.write(read_data)
wait_time = 0
# 如果不设置自动结束,就等待一段时间,如果一直没有新写入,就自动结束。如果设置了自动结束,就在写操作结束时结束播放
else:
if self.end:
print("用户手动终止")
break
elif auto_end & self.finish:
print("写操作完成,自动结束。")
break
else:
time.sleep(0.5)
wait_time += 0.5
print("完成流式音频播放...")
stream_out.stop_stream()
stream_out.close()
# 开始音频写入。可支持多次音频写入.streamchat是一个音频编码字节流iterator
def start_writing(self, streamchat):
self.writer = threading.Thread(target=self.write, args=(streamchat,))
self.writer.start()
# 开始音频播放
def start_playing(self, waittime_tostart=5):
self.player = threading.Thread(target=self.play, args=(waittime_tostart,))
self.player.start()
# 一次完整的音频写入+播放
def run(self, streamchat, waittime_tostart=5):
self.writer = threading.Thread(target=self.write, args=(streamchat,))
self.player = threading.Thread(target=self.play, args=(waittime_tostart, True))
self.writer.start()
self.player.start()
self.writer.join()
self.player.join()
def generate(text):
#网络请求流式获取音频字节流数据
yield audio_binary
player=Player()
streamchat=generate(text)
player.run(streamchat)
gradio对流式播放的支持似乎确实有些问题。详见 https://github.com/gradio-app/gradio/issues/8185