Question

I have a folder with several hundred wav files. I want to get the minimum length, in milliseconds, of the shortest wav file and the maximum length, respectively. I also want to get the total length of all files.

I know I can use sox and sed to get the length of a single wav file, like this

sox some_file.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p'

The easiest way I can think of is to use a Python script that loops trough all my files, since they all have generic, consecutive file names ({001-800}.wav), and call the above code. However, I'm not sure how to do that. I know subprocess should be the module to use, but I couldn't figure out how to pipe.

Currently I'm stuck with something along this line:

import subprocess
import shlex

min = 1000
max = 0
total = 0

for i in range(1,801):
    cmd = "sox %03d.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p" % i
    subprocess.call(shlex.split(cmd))

    # here is where I would catch the output and do the calculations with min, max, and total
Was it helpful?

Solution

cmd in your example is a shell pipeline. subprocess.call() doesn't call the shell by default i.e., your command should fail unless you specify shell=True (use string argument in this case). To get output, you could call:

output = subprocess.check_output(cmd, shell=True)

You could avoid calling shell commands and use pure Python parser demonstrated in How to get .avi files length question instead:

#!/usr/bin/env python
from glob import glob
from hachoir_metadata import extractMetadata
from hachoir_parser import createParser

entries = [(path, extractMetadata(createParser(path)).get('duration'))
           for path in glob(u"*.wav")]
print "Min: path(%s), duration(%s)" % min(entries, key=lambda (_,d): d)
print "Max: path(%s), duration(%s)" % max(entries, key=lambda (_,d): d)
print "Total: duration(%s seconds)" % sum(d.total_seconds() for _, d in entries)

To install the hachoir library, run:

$ pip install hachoir-{core,parser,metadata}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top