在Python中管道SoX - 子流程替代方案?

时间:2012-10-21 15:43:49

标签: python audio subprocess sox inter-process-communicat

我在应用程序中使用SoX。该应用程序使用它来对音频文件应用各种操作,例如修剪。

这很好用:

from subprocess import Popen, PIPE

kwargs = {'stdin': PIPE, 'stdout': PIPE, 'stderr': PIPE}

pipe = Popen(['sox','-t','mp3','-', 'test.mp3','trim','0','15'], **kwargs)
output, errors = pipe.communicate(input=open('test.mp3','rb').read())
if errors:
    raise RuntimeError(errors)

由于read()将完整文件加载到内存中,因此会导致大文件命中问题。这很慢,可能导致管道缓冲区溢出。存在一种解决方法:

from subprocess import Popen, PIPE
import tempfile
import uuid
import shutil
import os

kwargs = {'stdin': PIPE, 'stdout': PIPE, 'stderr': PIPE}
tmp = os.path.join(tempfile.gettempdir(), uuid.uuid1().hex + '.mp3')

pipe = Popen(['sox','test.mp3', tmp,'trim','0','15'], **kwargs)
output, errors = pipe.communicate()

if errors:
    raise RuntimeError(errors)

shutil.copy2(tmp, 'test.mp3')
os.remove(tmp)

所以问题如下:除了在Sox C API中编写Python扩展之外,还有其他方法吗?

1 个答案:

答案 0 :(得分:4)

SoX的Python包装器已经存在:sox。也许最简单的解决方案是切换到使用它而不是通过subprocess调用外部SoX命令行实用程序。

以下内容使用sox包在您的示例中实现了您想要的内容(请参阅documentation),并且可以使用 Linux macOS Python 2.7 3.4 3.5 (它可能也适用于Windows,但我无法测试,因为我没有访问Windows框):

>>> import sox
>>> transformer = sox.Transformer()  # create transformer 
>>> transformer.trim(0, 15)  # trim the audio between 0 and 15 seconds 
>>> transformer.build('test.mp3', 'out.mp3')  # create the output file 

注意:此答案用于提及不再维护的pysox包。感谢@erik的提示。