Reputation: 345
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
Upvotes: 1
Views: 1831
Reputation: 414235
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}
Upvotes: 2