python 的 ffmpy 不能处理使用 tempfile.TemporaryFile 制作的临时文件吗?

Doesn't python's ffmpy works with temporary files made using tempfile.TemporaryFile?

我正在制作一个函数,其目的是获取一个 mp3 文件并 分析和处理 它。所以,从 this SO answer 获得帮助,我正在制作一个临时 wav 文件,然后使用 python ffmpy 库我试图转换 mp3(实际给定文件)到 wav 文件。但要注意的是,我将上面生成的临时 wav 文件作为输出文件提供给 ffmpy 以将结果存储到,即我正在这样做:

import ffmpy
import tempfile
from scipy.io import wavfile

# audioFile variable is known here

tempWavFile = tempfile.TemporaryFile(suffix="wav")
ff_obj = ffmpy.FFmpeg(
                      global_options="hide_banner",
                      inputs={audioFile:None},
                      outputs={tempWavFile: " -acodec pcm_s16le -ac 1 -ar 44000"}
                     )

ff_obj.run()

[fs, frames] = wavfile.read(tempWavFile)
print(" fs is: ", fs)
print(" frames is: ", frames)

但在线 ff_obj.run() 出现此错误:

File "/home/tushar/.local/lib/python3.5/site-packages/ffmpy.py", line 95, in run
    stderr=stderr
  File "/usr/lib/python3.5/subprocess.py", line 947, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1490, in _execute_child
    restore_signals, start_new_session, preexec_fn)
TypeError: Can't convert '_io.TextIOWrapper' object to str implicitly

所以,我的问题是:

tempfile.TemporaryFile returns 类文件对象:

>>> tempWavFile = tempfile.TemporaryFile(suffix="wav")
>>> tempWavFile
<_io.BufferedRandom name=12>

另一方面,tempfile.mktemp returns 指向刚刚在文件系统上创建的真实文件的路径的字符串:

>>> tempWavFile = tempfile.mktemp('.wav')
>>> tempWavFile
'/var/folders/f1/9b4sf0gx0dx78qpkq57sz4bm0000gp/T/tmpf2117fap.wav'

创建 tempWavFile 后,将其传递给 ffmpy.FFmpeg,它将在单个命令中聚合输入和输出文件和参数,传递给 subprocess。命令行采用列表形式,可能如下所示:["ffmpeg", "-i", "input.wav", "output.wav"].

最后,ffmpy 将此列表传递给 subprocess.Popen,这就是当您使用 tempfile.TemporaryFile 时它会爆炸的地方。这是正常的,因为 subprocess 对您的参数一无所知,并希望它们都是字符串。当它看到 tempfile.TemporaryFile 返回的 _io.BufferedRandom 对象时,它不知道该怎么做。

所以,要修复它,只需使用 tempfile.mkstemp,这比 tempfile.TemporaryFile.

更安全

来自 the Python docs:

tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)
Creates a temporary file in the most secure manner possible.
...
Unlike TemporaryFile(), the user of mkstemp() is responsible for deleting the temporary file when done with it.


您最初提到的 mktemp,自 Python 2.3 以来已弃用(请参阅 docs),应替换为 mkstemp