python的ffmpy不适用于使用tempfile.TemporaryFile制作的临时文件吗?

时间:2017-06-08 11:38:44

标签: python-3.x audio ffmpeg signal-processing temporary-files

我正在创建一个功能,其目的是获取mp3文件并分析和处理。所以,从this得到帮助回答,我正在制作一个临时的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

所以,我的问题是:

  • 当我用tempWavFile = tempfile.TemporaryFile(suffix="wav")替换tempWavFile = tempfile.mktemp('.wav')时,没有错误发生,为什么会这样?
  • 这个错误意味着什么,它的发生原因是什么以及如何纠正?

1 个答案:

答案 0 :(得分:2)

tempfile.TemporaryFile返回类似文件的对象:

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

另一方面,tempfile.mktemp将字符串返回到刚刚在文件系统上创建的真实文件的路径:

>>> 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对你的参数一无所知,并期望它们都是字符串。当它看到_io.BufferedRandom返回的tempfile.TemporaryFile对象时,它不知道该怎么做。

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

来自the Python docs

  

tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)
  尽可能以最安全的方式创建临时文件   ...
  与TemporaryFile()不同,mkstemp()的用户负责在完成后删除临时文件。

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