PlayHT与Twilio流式传输仅出白噪音问题排查求助
在Twilio播放PlayHT流式音频仅出现白噪音的排查方案
我们尝试通过Twilio播放从PlayHT获取的mulaw格式流式音频,但仅听到白噪音。两端日志无报错,以下是相关代码,求排查思路。
Twilio函数代码
exports.handler = function(context, event, callback) { let twiml = new Twilio.twiml.VoiceResponse(); try { //const connect = twiml.connect(); console.log("start"); const connect = twiml.connect(); connect.stream({ name: "PlayHT", url: 'wss://f074-2a00-23a8-424f-b701-e862-5a32-4e45-397.ngrok-free.app' }); console.log(twiml.toString()); callback(null, twiml); } catch (error) { console.error("Error connecting to WebSocket:", error); callback(error); } };
WebSocket服务器核心代码
wss.on('connection', function connection(ws) { ws.on('message', async function incoming(message) { // Parse the JSON string into an object const messageObj = JSON.parse(message); const event = messageObj.event; if (event == 'start') { console.log('received: %s', message); const streamSid = messageObj.streamSid; // Create a test text stream const textStream = new Readable({ read() { this.push('This is a test'); this.push(null); // End of data }, }); // Stream audio from text const stream = await PlayHTAPI.stream(textStream, { voiceEngine: 'PlayHT2.0-turbo', voiceId: process.env.PLAYHT_VOICE_ID, output_format: "mulaw", quality: 'low', sample_rate: 8000 }); // Pipe the audio stream directly to the WebSocket stream.on('data', (chunk) => { console.log('sending: %s', chunk); // Encode chunk in base64 const base64Chunk = chunk.toString('base64'); // Prepare the JSON object in Twilio's expected format const twilioMessage = { event: "media", media: { track: "outbound", // or "inbound" depending on your use case payload: base64Chunk }, streamSid: streamSid }; // Send the JSON object as a string ws.send(JSON.stringify(twilioMessage)); }); stream.on('end', () => { const twilioMessage = { event: "mark", mark: { "name": "PlayHT" }, streamSid: streamSid }; // Send the JSON object as a string ws.send(JSON.stringify(twilioMessage)); console.log("--------------End stream--------------"); }); } else { if (event != 'media') { console.log('received: %s', message); } } }); });
排查方向
- 音频格式参数校验:确认PlayHT输出的mulaw音频是否严格符合Twilio要求——必须是8000Hz采样率、单声道。可以用ffmpeg命令直接验证:
ffmpeg -i test.mulaw -hide_banner,查看输出中的采样率和声道数。 - Base64编码正确性:将PlayHT返回的原始chunk保存为本地mulaw文件,再把该文件转成base64后解码回文件,对比两个文件是否完全一致。若不一致,说明编码环节存在问题。
- Twilio消息格式检查:确保发送给Twilio的JSON结构无错误,
track字段必须为"outbound",streamSid要和Twiliostart事件中返回的完全一致,不能有拼写错误或值不匹配。 - 流式传输时序与测试:在
start事件触发后,先发送一段已知有效的mulaw音频片段(比如提前录制的短语音),验证Twilio是否能正常播放,以此排除PlayHT流本身的问题。 - 消息大小控制:Twilio对单条媒体消息的payload大小有要求,建议将每个音频chunk拆分到160字节左右(对应20ms的8000Hz mulaw音频),过大的chunk可能导致解析失败。
内容的提问来源于stack exchange,提问作者Ovidiu Gliga
相关产品推荐
相关产品推荐

