我在应用程序中使用 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 扩展之外,还有其他方法可以替代这种方法吗?
最佳答案
SoX 的 Python 包装器已经存在: sox 。也许最简单的解决方案是切换到使用它,而不是通过 subprocess
调用外部 SoX 命令行实用程序。
以下使用 sox
包(请参阅 documentation )在示例中实现了您想要的内容,并且应该适用于 Linux 和 macOS on Python 2.7 , 也适用于 Windows 2.7 和 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 的提示。
关于python - 在 Python 中管道 SoX - 子进程替代方案?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12999361/