Piping SoX in Python - subprocess alternative?

Posted by Cochise Ruhulessin on Stack Overflow See other posts from Stack Overflow or by Cochise Ruhulessin
Published on 2012-10-21T15:43:48Z Indexed on 2012/10/21 17:01 UTC
Read the original article Hit count: 349

I use SoX in an application. The application uses it to apply various operations on audiofiles, such as trimming.

This works fine:

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)

This will cause problems on large files hower, since read() loads the complete file to memory; which is slow and may cause the pipes' buffer to overflow. A workaround exists:

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)

So the question stands as follows: Are there any alternatives to this approach, aside from writing a Python extension to the Sox C API?

© Stack Overflow or respective owner

Related posts about python

Related posts about audio