gpt4 book ai didi

python - 如何在flask服务器中使用ffmpeg在音频格式之间进行转换而不将文件写入磁盘?

转载 作者:行者123 更新时间:2023-12-01 06:37:00 25 4
gpt4 key购买 nike

我已经成功地在Python中使用ffmpeg来转换一些音频文件的格式,如下所示:

command = "ffmpeg -i audio.wav -vn -acodec pcm_s16le output.wav"
subprocess.call(command, shell=True)

但是我想在内存中执行此操作,并避免将输入和输出文件保存到磁盘。

我找到了以下代码来完成这样的事情(Passing python's file like object to ffmpeg via subprocess):

command = ['ffmpeg', '-y', '-i', '-', '-f', 'wav', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE)
wav, errordata = process.communicate(file)

但我很难在我的上下文中使用它。

我正在服务器上接收该文件,作为多部分/表单数据请求的一部分。

@server.route("/api/getText", methods=["POST"])
def api():
if "multipart/form-data" not in request.content_type:
return Response("invalid content type: {}".format(request.content_type))
# check file format
file = request.files['file']
if file:
print('**found file', file.filename)

现在我将该文件作为 FileStorage 对象 ( https://tedboy.github.io/flask/generated/generated/werkzeug.FileStorage.html )。该对象有一个流,可以使用 read 方法访问该流。所以我想我也许可以使用它作为 ffmpeg 的输入,如下所示:

f = file.read()
command = ['ffmpeg', '-y', '-i', '-', '-f', 'wav', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE)
wav, errordata = process.communicate(f)

但是这会产生以下错误:

AssertionError: Given audio file must be a filename string or a file-like object

我还尝试了在网上找到的另一种方法,使用 io.BytesIO,但我再也找不到源代码了:

memfile = io.BytesIO()  # create file-object
memfile.write(file.read()) # write in file-object
memfile.seek(0) # move to beginning so it will read from beginning

然后再试一次:

command = ['ffmpeg', '-y', '-i', '-', '-f', 'wav', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
wav, errordata = process.communicate(memfile)

这给我带来了以下错误:

TypeError: a bytes-like object is required, not '_io.BytesIO'

有人知道如何做到这一点吗?

更新

第一个错误信息实际上不是ffmpeg抛出的错误信息。正如 v25 在他的回答中正确指出的那样,第一种方法还返回一个字节对象,并且也是一个有效的解决方案。

尝试使用修改后的文件时,库 (speech_recognition) 抛出错误消息。万一有人遇到同样的问题,解决方案是:

正如错误消息所暗示的那样,ffmpeg(变量 wav)返回的字节对象必须转换为类似文件的对象。这可以很容易地完成,如下所示:

memfileOutput = io.BytesIO(wav)

最佳答案

根据您的评论,此问题似乎已通过以下方式修复:

wav, errordata = process.communicate(memfile.read())

我不是 100% 确定为什么在这里传递 f 不起作用,因为:

import io

print ('file.read()', type(file.read()))

memfile = io.BytesIO()
memfile.write(file.read())
memfile.seek(0)

print ('memfile', type(memfile))

print ('memfile.read()', type(memfile.read()))

给...

file.read() <class 'bytes'> # (f)
memfile <class '_io.BytesIO'>
memfile.read() <class 'bytes'>

因此,在您的情况下,fmemfile.read() 似乎属于同一类型。

我实际上不确定为什么前者会产生,AssertionError:给定的音频文件必须是文件名字符串或类似文件的对象

关于python - 如何在flask服务器中使用ffmpeg在音频格式之间进行转换而不将文件写入磁盘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com