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

向Twilio双向流发送Media音频播放出现噪音的问题排查求助

Google TTS转Twilio双向流播放出现静电噪音问题排查

TLDR:从Google TTS API获取mulaw/8000Hz格式音频,通过Twilio Media消息发送到双向流后,呼叫者仅听到刺耳的静电噪音,核心疑问如下:

  1. 我遗漏了什么?还有哪些未尝试的排查方案?
  2. 如何本地测试要发送给Twilio的mulaw/8000Hz字节是否可播放?为何Twilio对音频的判定与ffmpeg、sox或Audacity不一致?
  3. Twilio要求使用哪种base64编码类型(标准、标准无填充、URL安全、URL安全无填充)?

针对常见疑问的验证结果

  • 疑问:Twilio规定发送的音频需为audio/x-mulaw编码、8000Hz采样率,是否符合要求?
    答案:是。请求Google TTS时已明确指定mulaw编码和8000Hz采样率;将返回的base64字符串解码后保存到本地,ffprobe和soxi均确认音频参数符合要求。
  • 疑问:Google生成的mulaw音频附带WAV头,是否已移除头信息再发送给Twilio?
    答案:是。解码Google返回的base64字符串后,截取前44字节(WAV头大小),仅对剩余原始音频字节重新进行base64编码后发送;截取后的字节保存到本地,可作为mulaw/8000Hz原始数据导入Audacity并正常播放。
  • 疑问:是否正确对mulaw/8000Hz字节进行base64编码?
    答案:本地验证正确。将发送给Twilio的标准base64字符串解码后,导入Audacity可正常播放;已尝试所有常见base64编码类型(标准、标准无填充、URL安全、URL安全无填充),均未解决问题。
  • 疑问:是否正确格式化发送给Twilio的Media消息?
    答案:是。消息格式与Twilio官方示例完全一致。
  • 疑问:发送给Twilio的Media消息是否为WS Text消息?
    答案:是。
  • 疑问:是否在发送Media消息后发送了Mark消息?
    答案:是。

相关Rust代码

// Rust代码逻辑与Google TTS官方命令行示例一致
let audio_config = AudioConfig {
    audio_encoding: Some(AudioConfigAudioEncoding::MULAW),
    sample_rate_hertz: Some(8_000),
    ..Default::default()
};
// Google TTS API其他配置逻辑...

let payload = synthesize_response.audio_content.unwrap();
println!("{payload}");
// `payload` 是带WAV头的mulaw/800Hz音频的base64编码字符串

// Base64解码payload
let mut enc = Cursor::new(payload);
let mut decoder = read::DecoderReader::new(&mut enc, &engine::general_purpose::STANDARD);
let mut body = Vec::new();
decoder.read_to_end(&mut body).unwrap();
// `body` 为原始字节流;写入本地文件后,ffprobe和soxi可识别为mulaw/8000Hz音频,`play`命令可正常播放

// 移除Google返回音频中的WAV头
let trimmed = &body[44..];
// `trimmed` 为无头的mulaw/8000Hz原始音频;写入本地文件后,可作为mulaw编码、8000Hz音频导入Audacity正常播放

// 对无头原始音频重新进行base64编码
let re_encoded: String = engine::general_purpose::STANDARD.encode(trimmed);
// 构造发送给Twilio的Media消息
let outbound_media_meta = OutboundMediaMeta {
    payload: re_encoded,
};
let outbound_media = TwilioOutbound::Media {
    media: outbound_media_meta,
    stream_sid: stream_sid.clone(),
};
let json = serde_json::to_string(&outbound_media).unwrap();
println!("{json}");
// 验证JSON格式符合Twilio Media消息要求(包含`"event": "media"`字段)
let message = Message::Text(json);

sender.send(message).await.unwrap();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:33:14