在 Web 开发中,有时我们需要后端实时计算音频数据并立即播放,而不想先落盘成文件。Flask 作为轻量框架,借助生成器和流式响应就能实现动态生成并流式传输客户端音频。下面介绍具体做法。

后端动态生成音频流
我们可以使用 Python 的 wave 与 struct 模块在内存中合成简单的正弦波音频,并通过 Flask 的 Response 以流的形式返回。注意 MIME 类型要设为 audio/wav。
import wave
import struct
import math
from flask import Flask, Response
app = Flask(__name__)
def generate_sine_wave(duration=5, freq=440, rate=44100):
# 生成单声道 16bit 正弦波片段
num_samples = int(duration * rate)
for i in range(num_samples):
sample = 32767 * math.sin(2 * math.pi * freq * i / rate)
yield struct.pack('<h', int(sample))
@app.route('/audio')
def audio_stream():
def stream():
# 先写 wav 头,再持续输出采样数据
wav_header = wave.open('/dev/null', 'wb')
wav_header.setnchannels(1)
wav_header.setsampwidth(2)
wav_header.setframerate(44100)
# 由于是流式,这里仅示意头部构造
yield b'RIFF'
yield b'XXXX'
yield b'WAVE'
for chunk in generate_sine_wave(10, 440, 44100):
yield chunk
return Response(stream(), mimetype='audio/wav')
if __name__ == '__main__':
app.run(debug=True)
前端接收并播放
前端不需要特殊库,直接用 HTML5 Audio 元素指向流地址即可,浏览器会边收边播。
<audio controls> <source src="/audio" type="audio/wav"> 你的浏览器不支持音频播放 </audio>
注意事项
- 流式音频建议用 chunked transfer,Flask 默认支持。
- 若生成逻辑重,可放到线程或异步任务,避免阻塞主进程。
- 动态生成时注意设置正确的采样率和位深,否则前端播放失真。
小结
通过 Flask 的 Response 与 Python 生成器,我们可以把实时算出的音频直接流式发给客户端。这种方式适合提示音、实时合成等场景,扩展时只需替换 generate_sine_wave 里的算法。