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

Coc*_*sin 4 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)
Run Code Online (Sandbox Code Playgroud)

这将导致大文件出现问题,因为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)
Run Code Online (Sandbox Code Playgroud)

所以问题如下:除了为 Sox C API 编写 Python 扩展之外,是否还有其他方法可以替代这种方法?

Ped*_*ano 5

SoX 的 Python 包装器已经存在:sox。也许最简单的解决方案是切换到使用它,而不是通过subprocess.

以下使用sox包(请参阅文档)在示例中实现了您想要的内容,并且应该在LinuxmacOS上运行Python 2.73.43.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 
Run Code Online (Sandbox Code Playgroud)

注意:这个答案曾经提到不再维护的pysox包。感谢@erik 的提示。

  • 奇怪的是,存在 2011 年的 [pysox 版本 0.3.6](https://pypi.python.org/pypi/pysox/0.3.6.alpha) 和 [sox 1.2.0,一个围绕 SoX 的 Python 包装器](https://pypi.python.org/pypi/pysox/0.3.6.alpha) /pypi.python.org/pypi/sox) 从 2016 年开始。最后一个的 github 页面命名为 [pysox](https://github.com/rabitt/pysox)!但最后一个不适用于 Python 3。:-( (2认同)
  • 维护的 [python 包装器 **sox**](https://pypi.python.org/pypi/sox) 似乎现在可以与 python 3 一起使用!并且有1.3.2版本。 (2认同)