我正在开发一款软件,使用 Flask Web 服务通过 HTTP 从源流式传输音频。我可以通过
sounddevice
获取声音帧,并通过具有 yield
和正确的 mimetype 的 Flask 路由将它们路由到浏览器,但是原始音频格式对于远程流式传输来说非常麻烦,并且在涉及到时并不是最好的客户端兼容性。
我很想使用
pydub
将原始音频帧转换为 mp3 或 ogg 等格式,但无论是从 文档还是从 源代码,我都不清楚如何实现 on-the - 进行格式转换,无需通过 .export()
将输出转储到文件。
到目前为止我的代码框架是这样的:
### audio.py
import queue
import sounddevice as sd
from pydub.audio_segment import AudioSegment
def input_stream(device, sample_width=2, sample_rate=44100,
channels=1, latency=0, blocksize=2048, timeout=5.0):
audio_queue = queue.Queue()
def audio_callback(indata, frames, time_duration, status):
audio = AudioSegment(indata, sample_width=sample_width,
channels=channels, frame_rate=sample_rate)
# Some pydub magic should happen here to convert the raw frame to mp3/ogg
audio_queue.put(audio.raw_data)
with sd.InputStream(samplerate=sample_rate, device=device,
channels=channels, callback=audio_callback,
latency=latency, blocksize=blocksize):
while not recording_terminated():
yield audio_queue.get(block=True, timeout=timeout)
### web.py
from flask import route, request, Response
from audio import input_stream
@route('/sound/stream', methods=['GET'])
def get_sound_feed():
device = request.args.get('device')
return Response(input_stream(device), mimetype='audio/ogg')
如何将
AudioSegment
中的原始 audio_callback
对象转换为适合网络流媒体的压缩 mp3/ogg?我知道可以通过 AudioSegment.from_file
从 mp3 创建片段,或者通过 .export()
将其转储到 mp3 文件,但这并不是一个真正的选择,因为此类 I/O 操作会引入不可忽略的延迟。我认为理论上可能可以破解 .export()
以将其转储到套接字或 fifo 文件描述符,但这对我来说听起来有点像一个 hacky 解决方法,而且我不确定它是否足以满足文件描述符以提供 .write()
方法,或者如果它因需要其他方法(例如 seek
)而中断。.export()
函数在执行结束时返回文件对象。
convert_file = audio_file.export(format="flac")
我已经这样做了,我可以像使用
open()
函数一样处理 Convert_file 。 (我为自己的项目转换为 flac,但你可以做任何格式)
我发现,如果您不提供文件名,
.export()
我希望您能找到解决问题的方法。
# Load input song
song = from_mp3("my_song.mp3")
# create new empty BytesIO
exported_io = BytesIO()
# export to BytesIO object
song.export(exported_io, format="wav")
然后可以对此 BytesIO 对象执行任何操作。使用此方法不会创建任何物理文件。