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

如何在FastAPI的单个请求中实现音频上传与流式返回?

解决方案:FastAPI 接收音频并流式返回结果

先明确核心结论

FastAPI 的 POST 端点完全支持返回 StreamingResponse,你遇到的「无法流式返回」大概率是客户端、中间件或代码逻辑的问题,而非框架限制。以下是几种可行方案:


方案一:修复 POST + StreamingResponse 流程

先排查并解决当前 POST 端点的流式问题:

  1. 检查客户端流式支持
    部分客户端默认不处理 POST 请求的流式响应,比如浏览器原生表单提交。改用支持流式的客户端调用方式:

    # Python requests 示例
    import requests
    
    with open("input.wav", "rb") as f:
        # 开启 stream=True 以接收流式响应
        response = requests.post("http://localhost:8000/stream-audio", files={"audio_file": f}, stream=True)
        with open("output.wav", "wb") as out_f:
            for chunk in response.iter_content(chunk_size=1024):
                out_f.write(chunk)
    
  2. 实现真正的实时流式处理
    你的示例代码是先生成完整文件再读取返回,并非实时流式。如果要边处理边返回,直接从处理流程中 yield 数据:

    from fastapi import UploadFile
    from fastapi.responses import StreamingResponse
    
    def process_audio_stream(input_file: UploadFile):
        # 模拟边读输入边生成处理后的音频块
        while chunk := input_file.file.read(1024):
            # 替换为你的实际音频处理逻辑
            processed_chunk = chunk  # 示例:直接返回原数据
            yield processed_chunk
    
    @app.post("/stream-audio")
    def stream_audio(audio_file: UploadFile):
        return StreamingResponse(process_audio_stream(audio_file), media_type="audio/wav")
    
  3. 禁用中间件缓存
    若使用 Nginx 等反向代理,默认会缓冲响应导致流式失效,需配置禁用缓冲:

    # Nginx 配置示例
    location /stream-audio {
        proxy_pass http://your-fastapi-server;
        proxy_buffering off;  # 关键:禁用缓冲
        proxy_set_header Connection "";
    }
    

方案二:拆分上传与请求(两步式)

如果环境限制无法用 POST 流式返回,可拆分为两个独立端点:

  1. POST 上传音频并触发处理

    import uuid
    from fastapi import BackgroundTasks, UploadFile
    
    # 生产环境建议用数据库/分布式缓存替代内存存储
    processed_tasks = {}
    
    def process_audio_task(file_content: bytes, task_id: str):
        # 音频处理逻辑,生成处理后的音频内容
        processed_content = file_content  # 替换为实际处理
        processed_tasks[task_id] = processed_content
    
    @app.post("/upload-audio")
    async def upload_audio(audio_file: UploadFile, background_tasks: BackgroundTasks):
        task_id = str(uuid.uuid4())
        file_content = await audio_file.read()
        background_tasks.add_task(process_audio_task, file_content, task_id)
        return {"task_id": task_id}
    
  2. GET 流式返回处理结果

    def iter_processed_audio(task_id: str):
        yield processed_tasks.get(task_id, b"")
    
    @app.get("/get-audio/{task_id}")
    def get_audio(task_id: str):
        if task_id not in processed_tasks:
            return {"error": "任务未找到或处理中"}
        return StreamingResponse(iter_processed_audio(task_id), media_type="audio/wav")
    

方案三:使用 WebSocket 双向流式传输

如果需要更实时的交互(边上传边接收处理结果),用 WebSocket 实现双向流式:

from fastapi import WebSocket

@app.websocket("/ws-audio")
async def websocket_audio(websocket: WebSocket):
    await websocket.accept()
    while True:
        # 接收客户端分块发送的音频数据
        chunk = await websocket.receive_bytes()
        # 处理当前音频块
        processed_chunk = chunk  # 替换为实际处理逻辑
        # 实时返回处理后的音频块
        await websocket.send_bytes(processed_chunk)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:25:08