python - 如何在没有中间音频文件的情况下转换 pydub `AudioSegment` 以用于流式传输?
问题描述
我正在开发一种软件,以使用 Flask 网络服务通过 HTTP 流式传输来自源的音频。sounddevice
我可以通过带有正确 mimetype 的 Flask 路由获取声音帧并将它们路由到浏览器yield
,但是原始音频格式对于远程流式传输来说非常麻烦,并且在客户端兼容性方面并不是最好的。
我很想用来将原始音频帧转换为像 mp3 或 ogg 这样的格式,但是从文档和源代码pydub
中我都不清楚如何在不转储输出的情况下实现即时格式转换通过..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?我知道可以通过 mp3 创建一个片段AudioSegment.from_file
,或者通过 将其转储到 mp3 文件.export()
中,但这并不是一个真正的选择,因为这样的 I/O 操作会引入不可忽略的延迟。我认为理论上可以破解.export()
以将其转储到套接字或 fifo 文件描述符,但这对我来说听起来有点像 hacky 解决方法,而且我不确定文件描述符是否足以提供.write()
方法,或者它是否会因为seek
需要其他方法(例如)而中断。
解决方案
我不知道您是否可以阻止pydub将文件保存到磁盘,但是您可以在转换结束时获取文件而无需重新打开它。实际上,该.export()
函数在执行结束时返回文件对象。
convert_file = audio_file.export(format="flac")
我已经这样做了,我可以像使用该open()
函数一样处理 convert_file。(我为自己的项目转换为 flac,但您可以使用任何格式)
我发现如果您不提供文件名,该.export()
函数甚至不会将文件写入磁盘而不会出现任何错误。
我希望您能找到解决问题的方法。
推荐阅读
- laravel - Laravel 不向 Memcached 写入会话
- python-3.x - 如何从 python 文件中导入所有函数
- javascript - 如何使用 JSON 文件开发具有多个下拉菜单的现场产品过滤程序?
- c# - Count 和 foreach 产生不同的结果
- ios - 如何在 swift 中从 viewmodel 调用 ViewController 中的方法?
- linux - 忽略bash中重定向输出中的空格
- scala - 在 main 上调用这个 Scala 方法的正确方法是什么?
- python - 如何用硒提取href链接标题?
- c# - xamarin 绑定类属性
- pandas - 如何使用 boto3 从 S3bucket 子文件夹中获取文件内容?