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

FastAPI双API间BytesIO音频文件传输损坏问题排查

问题原因与解决方案

原因分析

核心问题是BytesIO的文件指针位置错误:

  • API1中调用sf.read(audio)读取音频内容时,会将BytesIO对象的内部指针移动到文件末尾。
  • 后续执行audio.read()时,指针已处于末尾位置,无法读取到任何音频数据,导致返回的Response内容为空。
  • API1中pickle保存的33KB文件是完整的BytesIO对象(包含原始内容和指针状态),但返回给API2的是空数据,所以API2生成的BytesIO仅保留了对象本身的结构(42字节),没有实际音频内容。

解决办法

方法1:重置BytesIO指针

在需要读取BytesIO内容前,调用seek(0)将指针重置到开头:

# API1 修改后的代码
(...)

audio = tts.generate_audio(translation,final,wavdata)
samples, samplerate = sf.read(audio)
audio.seek(0)  # 重置指针到开头,保证后续操作能读取完整内容
sd.play(samples, samplerate)
sd.wait()
with open("obj1.pickle", "wb") as f:
    pickle.dump(audio, f)
audio.seek(0)  # 再次重置指针,确保返回完整音频数据
return Response(content=audio.read(), media_type="audio/wav")

方法2:提前提取字节内容

如果需要多次使用音频数据,建议先将BytesIO的全部内容提取为bytes变量,避免指针问题:

# API1 修改后的代码
(...)

audio = tts.generate_audio(translation,final,wavdata)
audio_bytes = audio.getvalue()  # 一次性获取全部音频字节
# 用新的BytesIO包装字节数据给sf.read使用
samples, samplerate = sf.read(io.BytesIO(audio_bytes))
sd.play(samples, samplerate)
sd.wait()
with open("obj1.pickle", "wb") as f:
    pickle.dump(io.BytesIO(audio_bytes), f)
# 直接返回字节数据,无需处理指针
return Response(content=audio_bytes, media_type="audio/wav")

API2的代码无需修改,只要API1返回了完整的音频数据,r.content就会包含完整内容,生成的BytesIO也会和API1的一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:10:13