基于Twilio实时API存储媒体流MP3:音质差且慢放问题求助
问题原因及解决方案
核心问题
- 双声道处理错误:当设置
track='both_tracks'时,Twilio推送的是立体声μ-law音频(左右声道分别对应通话双方),但你的代码按单声道处理,导致音频帧错位,出现播放速度慢、音质失真。 - 低采样率兼容性差:G.711原生8kHz采样率,多数MP3播放器对该采样率支持不佳,易引发播放速度异常。
修正后的代码
@app.websocket("/store-stream") async def handle_store_stream(ws: WebSocket): await ws.accept() left_pcm = bytearray() right_pcm = bytearray() try: async for message in ws.iter_text(): data = json.loads(message) event = data['event'] if event == "media": payload = data["media"]["payload"] ulaw_data = base64.b64decode(payload) # 拆分双声道μ-law数据:每两个字节对应左右声道各一个样本 left_ulaw = ulaw_data[::2] # 取偶数索引字节(左声道) right_ulaw = ulaw_data[1::2] # 取奇数索引字节(右声道) # 分别将μ-law转换为16位线性PCM left_pcm_chunk = audioop.ulaw2lin(left_ulaw, 2) right_pcm_chunk = audioop.ulaw2lin(right_ulaw, 2) left_pcm.extend(left_pcm_chunk) right_pcm.extend(right_pcm_chunk) if event == "stop": # 将左右声道PCM交织成立体声数据 stereo_pcm = bytearray() for l_byte, r_byte in zip(left_pcm, right_pcm): stereo_pcm.extend([l_byte, r_byte]) # 创建AudioSegment对象,指定立体声参数 audio_segment = AudioSegment( data=bytes(stereo_pcm), sample_width=2, # 16位采样宽度 frame_rate=8000, # 原生8kHz采样率 channels=2 # 立体声 ) # 重采样到16kHz(提升播放器兼容性) audio_segment = audio_segment.set_frame_rate(16000) # 导出MP3,指定比特率优化音质 audio_segment.export('audio.mp3', format="mp3", bitrate="64k") break except Exception as e: print(f"Error processing stream: {e}")
关键修正点
- 拆分双声道:从Twilio的μ-law数据中分离左右声道,分别解码为PCM后交织成立体声,避免数据错位。
- 重采样优化:将8kHz采样率提升至16kHz,解决多数播放器对低采样率的兼容问题。
- 指定立体声参数:创建
AudioSegment时明确channels=2,确保音频按立体声解析。 - 比特率设置:导出MP3时指定
bitrate参数(如64k),平衡音质和文件大小。
额外建议
- 如果不需要录制双方音频,可将TwiML中的
track改为inbound_track或outbound_track,对应仅录制用户或AI的音频,此时代码可按单声道逻辑处理。 - 增加异常捕获逻辑,避免因WebSocket断开、数据格式异常等情况导致录音失败。
内容的提问来源于stack exchange,提问作者Lucasvan
相关产品推荐
相关产品推荐

