You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure SpeechSynthesizer.speak_text_async()是否真异步?如何实现流式异步合成?

实现Azure SpeechSynthesizer异步实时文本转语音

要解决调用result.get()阻塞主线程,同时实现合成过程中实时获取音频数据的问题,有两种实用方案:

方案一:多线程分离合成与音频拉取

把音频数据的拉取逻辑放到单独线程,主线程启动异步合成后,拉取线程可以实时从PullAudioOutputStream读取数据,无需等待整个合成完成。

示例代码:

import threading
import azure.cognitiveservices.speech as speechsdk

def pull_audio(pull_stream):
    buffer = bytearray(1024)
    while True:
        read_bytes = pull_stream.read(buffer)
        if read_bytes == 0:
            break
        # 这里替换成你的音频数据处理逻辑(比如播放、写入文件)
        print(f"获取到 {read_bytes} 字节音频数据")

# 初始化Speech配置
speech_config = speechsdk.SpeechConfig(subscription="你的订阅密钥", region="你的服务区域")
pull_stream = speechsdk.audio.PullAudioOutputStream()
audio_config = speechsdk.audio.AudioOutputConfig(stream=pull_stream)
synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)

# 启动拉取音频的后台线程
pull_thread = threading.Thread(target=pull_audio, args=(pull_stream,))
pull_thread.start()

# 启动异步合成,无需立即阻塞等待
future = synthesizer.speak_text_async("这是一段较长的测试文本,能直观看到实时拉取数据的效果")

# 主线程可继续执行其他任务(比如处理UI、业务逻辑)
print("主线程正在执行其他操作...")

# 可选:等待合成完成后关闭流、回收线程
result = future.get()
pull_stream.close()
pull_thread.join()

del synthesizer

方案二:利用SDK原生事件监听(推荐)

Azure Speech SDK提供了audio_data_received事件,每当合成出一段音频数据就会触发回调,无需手动管理流的拉取,代码更简洁。

示例代码:

import azure.cognitiveservices.speech as speechsdk

def handle_audio_data(evt):
    # evt.result.audio_data 就是当前生成的音频字节数据
    print(f"收到音频数据,长度:{len(evt.result.audio_data)}")
    # 这里添加你的数据处理逻辑(如播放、存储)

def handle_synthesis_done(evt):
    print("文本转语音合成完成")

# 初始化配置
speech_config = speechsdk.SpeechConfig(subscription="你的订阅密钥", region="你的服务区域")
# 无需指定输出流,直接通过事件获取数据
synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)

# 绑定事件回调
synthesizer.audio_data_received.connect(handle_audio_data)
synthesizer.synthesis_completed.connect(handle_synthesis_done)

# 启动异步合成,主线程不阻塞
future = synthesizer.speak_text_async("这是一段用于测试的长文本,验证实时接收音频的功能")

# 主线程继续执行其他任务
print("主线程处理其他业务...")

# 可选:如果需要等待合成结束再执行后续逻辑,才调用get()
# result = future.get()

del synthesizer

关键说明

  • 原代码中result.get()会阻塞是因为该方法会等待异步合成任务完全结束才返回。
  • 两种方案都能实现“合成过程中实时获取数据”的需求,方案二更贴合SDK的设计,无需手动管理线程和流的生命周期。

内容的提问来源于stack exchange,提问作者brentlyjr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:26:09