Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在flask server中使用ffmpeg在音频格式之间转换,而不将文件写入磁盘?_Python_Flask_Ffmpeg - Fatal编程技术网

Python 如何在flask server中使用ffmpeg在音频格式之间转换,而不将文件写入磁盘?

Python 如何在flask server中使用ffmpeg在音频格式之间转换,而不将文件写入磁盘?,python,flask,ffmpeg,Python,Flask,Ffmpeg,我成功地在python中使用ffmpeg转换了一些音频文件的格式,如下所示: command = "ffmpeg -i audio.wav -vn -acodec pcm_s16le output.wav" subprocess.call(command, shell=True) 但是,我希望在内存中执行此操作,并避免将输入和输出文件保存到磁盘 我找到了以下代码来执行此操作(): 但我很难在我的上下文中使用它 作为多部分/表单数据请求的一部分,我正在服务器上接收该文件 @server.rout

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

command = "ffmpeg -i audio.wav -vn -acodec pcm_s16le output.wav"
subprocess.call(command, shell=True)
但是,我希望在内存中执行此操作,并避免将输入和输出文件保存到磁盘

我找到了以下代码来执行此操作():

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

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

@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对象()。此对象有一个流,可以使用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
TypeError: a bytes-like object is required, not '_io.BytesIO'
我还尝试了另一种我在网上找到的方法,使用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)
这会导致以下错误:

AssertionError: Given audio file must be a filename string or a file-like object
TypeError: a bytes-like object is required, not '_io.BytesIO'
有人知道怎么做吗

更新

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

试图处理修改后的文件时,库(语音识别)抛出错误消息。在不太可能的情况下,如果有人遇到相同的问题,请在此提供解决方案:

如错误消息所示,ffmpeg(变量wav)返回的反对字节必须转换为类似文件的对象。这样做很容易:

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

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'>
file.read()#(f)
内存文件
memfile.read()
因此,在您的案例中,
f
memfile.read()
属于同一类型


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

如何
wav,errordata=process.communicate(memfile.read())
我自己也不清楚。等我有机会再看一次。能否将此添加到答案中:process=subprocess.Popen(command,stdin=subprocess.PIPE,stdout=subprocess.PIPE)?没有它,wav将一无是处。没有问题!我认为这可能不应该添加,因为该部分包含在问题中,并且答案包括相关的问题行。我之所以提到它,是因为我没有将其包含在问题(标准部分)中。但无论如何,我可以编辑这个问题,以防将来有人遇到它。我还弄明白了为什么我在第一种方法中会收到错误消息。这是我的错,实际上不是ffmpeg抛出的错误消息。我已经在这个问题上写了一些更新,以防有人怀疑。