Python中Twilio通话流发送TTS媒体事件无声音问题排查
问题排查与解决方案
1. gTTS生成格式错误,后续处理失效
gTTS默认输出的是MP3文件,你把它存成.wav后缀并不会改变实际格式,后续用audioop处理MP3数据必然出错。必须先将MP3转成Twilio要求的原始音频格式(8kHz、单声道、16位PCM)。
解决方法:用pydub库完成格式转换:
from pydub import AudioSegment speak = 'Hallo Welt' tts = gTTS(text=speak, lang='de') temp_mp3 = 'temp_audio.mp3' tts.save(temp_mp3) # 转成8kHz、单声道、16位PCM的WAV audio = AudioSegment.from_mp3(temp_mp3) audio = audio.set_frame_rate(8000).set_channels(1).set_sample_width(2) temp_wav = 'temp_audio.wav' audio.export(temp_wav, format='wav') # 读取原始PCM数据(跳过44字节的WAV文件头) with open(temp_wav, 'rb') as f: audio_data = f.read()[44:] os.remove(temp_mp3) os.remove(temp_wav)
2. 音频编码需匹配Twilio要求
Twilio媒体流要求的audio/x-mulaw是基于8kHz单声道16位PCM的编码,用上面的方法得到正确源数据后,再转μ-law:
import audioop audio_data = audioop.lin2ulaw(audio_data, 2) payload = base64.b64encode(audio_data).decode('utf-8')
3. 媒体事件格式与StreamSid验证
streamSid必须是当前活跃通话流的正确SID,要从Twilio触发的初始start事件中获取,不能硬编码或使用无效值。- 检查媒体事件JSON的拼写:
event字段值为media,streamSid大小写正确,没有多余或缺失的字段。
4. 确认WebSocket连接状态
发送媒体前要确保WebSocket处于活跃状态,避免连接断开导致发送失败:
if ws.readyState == 1: # 1代表OPEN状态 ws.send(json.dumps(media_response)) else: print("WebSocket连接已断开")
完整修正代码示例
import gTTS import os import audioop import base64 import json from pydub import AudioSegment # 从Twilio的start事件中获取正确的streamSid sid = "your_active_stream_sid" speak = 'Hallo Welt' tts = gTTS(text=speak, lang='de') temp_mp3 = 'temp_audio.mp3' tts.save(temp_mp3) # 转换音频格式 audio = AudioSegment.from_mp3(temp_mp3) audio = audio.set_frame_rate(8000).set_channels(1).set_sample_width(2) temp_wav = 'temp_audio.wav' audio.export(temp_wav, format='wav') # 读取原始PCM数据 with open(temp_wav, 'rb') as f: audio_data = f.read()[44:] # 清理临时文件 os.remove(temp_mp3) os.remove(temp_wav) # 转μ-law编码并生成payload audio_data = audioop.lin2ulaw(audio_data, 2) payload = base64.b64encode(audio_data).decode('utf-8') # 构造并发送媒体事件 media_response = { 'event': 'media', 'streamSid': sid, 'media': { 'payload': payload, 'type': 'audio/x-mulaw', } } if ws.readyState == 1: ws.send(json.dumps(media_response)) else: print("WebSocket连接已断开")
额外注意事项
- 安装依赖:
pip install gTTS pydub,同时要确保系统安装了ffmpeg并配置好环境变量(pydub依赖ffmpeg处理音频转换)。 - 测试时可先用已知正确的μ-law音频文件验证Twilio播放逻辑,排除TTS转换环节的问题后再整合完整流程。
内容的提问来源于stack exchange,提问作者CooleMuetze
相关产品推荐
相关产品推荐

