Azure文本转语音音频流回传Twilio无响应问题排查
问题分析与解决方案
一、音频回传无声音的问题排查
1. TwiML指令顺序错误
你的TwiML代码中,<Connect>之后直接跟着<Say>指令,这会导致Twilio建立WebSocket连接后,立即执行<Say>并结束通话。TwiML按顺序执行,<Connect>不会阻塞后续指令,当WebSocket连接建立后,Twilio会继续处理<Say>,播放完成后直接断开通话,此时回传音频时通话已终止,自然听不到声音。
修复方法:移除后续的<Say>指令,确保通话在WebSocket连接期间保持活跃:
const response = new VoiceResponse(); const connect = response.connect(); const stream = connect.stream({ url: "wss://<my_websocket_address>", }); res.type("text/xml"); res.send(response.toString());
2. TTS返回值错误,未传递正确Base64字符串
textToSpeech函数返回的是PassThrough流对象,但WebSocket回传的JSON要求payload是Base64字符串,而非流对象,这会导致Twilio无法解析音频数据。
修复方法:修改textToSpeech直接返回Base64字符串:
const textToSpeech = async (text) => { return new Promise((resolve, reject) => { const speechConfig = sdk.SpeechConfig.fromSubscription( constants.subscriptionkey, constants.region ); speechConfig.speechSynthesisLanguage = "en-US"; speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural"; speechConfig.speechSynthesisOutputFormat = sdk.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoMULaw; const synthesizer = new sdk.SpeechSynthesizer(speechConfig, null); synthesizer.speakTextAsync( text, (result) => { const { audioData } = result; synthesizer.close(); const base64Audio = Buffer.from(audioData).toString("base64"); console.log("TTS DONE"); resolve(base64Audio); }, (error) => { synthesizer.close(); reject(error); } ); }); };
回传代码直接使用返回的字符串:
let payload = await tts.textToSpeech("Hello, how can i help you?") var json = { "event": "media", "streamSid": "<从Twilio的start事件中获取的streamSid>", "media": { "payload": payload } } this.connection.send(JSON.stringify(json))
3. StreamSid硬编码,未使用实际会话的StreamSid
你代码中的streamSid是固定值,但每个通话的StreamSid是唯一的,由Twilio在WebSocket连接建立时发送的start事件提供。硬编码会导致Twilio无法关联你的media事件到正确通话流。
修复方法:监听WebSocket的start事件,动态获取并保存StreamSid:
// WebSocket消息监听示例 connection.on('message', (message) => { const data = JSON.parse(message); if (data.event === 'start') { this.currentStreamSid = data.streamSid; // 保存当前会话的streamSid } }); // 回传时使用动态获取的streamSid var json = { "event": "media", "streamSid": this.currentStreamSid, "media": { "payload": payload } } this.connection.send(JSON.stringify(json))
4. 未正确序列化JSON对象
直接将JSON对象传给connection.send()会导致格式错误,WebSocket的send方法需要接收字符串类型数据。
修复方法:使用JSON.stringify()将对象转为字符串后发送,如上述代码所示。
二、Twilio控制台查看WebSocket消息的方法
可以通过Twilio Debugger查看WebSocket相关事件和消息:
- 登录Twilio控制台,进入Monitor -> Debugger。
- 筛选
Media Stream相关事件,即可查看WebSocket连接建立、收发消息的详情,包括你发送的media事件和Twilio的响应。 - 也可在具体通话记录详情页(Monitor -> Calls,点击对应通话)查看该通话关联的Media Stream日志。
内容的提问来源于stack exchange,提问作者Swapnil Pandey
相关产品推荐
相关产品推荐

