Get .wav file length or duration

I'm looking for a way to find out the duration of a audio file (.wav) in python. So far i had a look at python wave library, mutagen, pymedia, pymad i was not able to get the duration of the wav file. Pymad gave me the duration but its not consistent.

Thanks in advance.


The duration is equal to the number of frames divided by the framerate (frames per second):

import wave
import contextlib
fname = '/tmp/test.wav'
with contextlib.closing(wave.open(fname,'r')) as f:
    frames = f.getnframes()
    rate = f.getframerate()
    duration = frames / float(rate)
    print(duration)

Regarding @edwards' comment, here is some code to produce a 2-channel wave file:

import math
import wave
import struct
FILENAME = "/tmp/test.wav"
freq = 440.0
data_size = 40000
frate = 1000.0
amp = 64000.0
nchannels = 2
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
data = [(math.sin(2 * math.pi * freq * (x / frate)),
        math.cos(2 * math.pi * freq * (x / frate))) for x in range(data_size)]
try:
    wav_file = wave.open(FILENAME, 'w')
    wav_file.setparams(
        (nchannels, sampwidth, framerate, nframes, comptype, compname))
    for values in data:
        for v in values:
            wav_file.writeframes(struct.pack('h', int(v * amp / 2)))
finally:
    wav_file.close()

If you play the resultant file in an audio player, you'll find that is 40 seconds in duration. If you run the code above it also computes the duration to be 40 seconds. So I believe the number of frames is not influenced by the number of channels and the formula above is correct.


the librosa library can do this: librosa

import librosa
librosa.get_duration(filename='my.wav')

A very simple method is to use soundfile (formerly pysoundfile).

Here's some example code of how to do this:

import soundfile as sf
f = sf.SoundFile('447c040d.wav')
print('samples = {}'.format(f.frames))
print('sample rate = {}'.format(f.samplerate))
print('seconds = {}'.format(f.frames / f.samplerate))

The output for that particular file is:

samples = 232569
sample rate = 16000
seconds = 14.5355625

This aligns with soxi:

Input File     : '447c040d.wav'
Channels       : 1
Sample Rate    : 16000
Precision      : 16-bit
Duration       : 00:00:14.54 = 232569 samples ~ 1090.17 CDDA sectors
File Size      : 465k
Bit Rate       : 256k
Sample Encoding: 16-bit Signed Integer PCM

we can use ffmpeg to get the duration of any video or audio files.

To install ffmpeg follow this link

import subprocess
import re
 
process = subprocess.Popen(['ffmpeg',  '-i', path_of_wav_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
matches = re.search(r"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout.decode(), re.DOTALL).groupdict()
 
print(matches['hours'])
print(matches['minutes'])
print(matches['seconds'])