Get .wav file length or duration

PythonAudio

Python Problem Overview


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.

Python Solutions


Solution 1 - Python

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.

Solution 2 - Python

the librosa library can do this: librosa

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

Solution 3 - Python

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

Solution 4 - Python

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'])

Solution 5 - Python

import os
path="c:\\windows\\system32\\loopymusic.wav"
f=open(path,"r")

#read the ByteRate field from file (see the Microsoft RIFF WAVE file format)
#https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
#ByteRate is located at the first 28th byte
f.seek(28)
a=f.read(4)

#convert string a into integer/longint value
#a is little endian, so proper conversion is required
byteRate=0
for i in range(4):
	byteRate=byteRate + ord(a[i])*pow(256,i)

#get the file size in bytes
fileSize=os.path.getsize(path)	

#the duration of the data, in milliseconds, is given by
ms=((fileSize-44)*1000)/byteRate

print "File duration in miliseconds : " % ms
print "File duration in H,M,S,mS : " % ms/(3600*1000) % "," % ms/(60*1000) % "," % ms/1000 % "," ms%1000
print "Actual sound data (in bytes) : " % fileSize-44  
f.close()

Solution 6 - Python

Let,T be the duration between 2 consecutive samples. So, we can write t = nT or t = n/Fs.

from scipy.io import wavfile
Fs, data = wavfile.read('filename.wav')
n = data.size
t = n / Fs

Solution 7 - Python

I was trying to get the length of different format of an audio file other than '.wav' and I tried a few of the above solution but didn't work for me

This is what worked for me :

from pydub.utils import mediainfo
mediainfo('audiofile')['duration']

Solution 8 - Python

To find length of music file, audioread module can be used,

install audioread: pip install audioread

then use this code:

import audioread
with audioread.audio_open(filepath) as f:
    totalsec = f.duration
    min,sec = divmod(totalsec,60) # divides total time in minute  and second 
                                    #and store it in min and sec variable respectively

Solution 9 - Python

Another solution with pydub:

import pydub
audio_seg = AudioSegment.from_wav('mywav.wav')
total_in_ms = len(audio_seg)

Solution 10 - Python

This is short and needs no modules, works with all operating systems:

import os
os.chdir(foo) # Get into the dir with sound
statbuf = os.stat('Sound.wav')
mbytes = statbuf.st_size / 1024
duration = mbytes / 200

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPannuView Question on Stackoverflow
Solution 1 - PythonunutbuView Answer on Stackoverflow
Solution 2 - PythonMaxView Answer on Stackoverflow
Solution 3 - PythonDave CView Answer on Stackoverflow
Solution 4 - PythonVishwanath HiremathView Answer on Stackoverflow
Solution 5 - PythondeAngelView Answer on Stackoverflow
Solution 6 - PythonRajan saha RajuView Answer on Stackoverflow
Solution 7 - PythonAaditya UraView Answer on Stackoverflow
Solution 8 - Pythonuser12167151View Answer on Stackoverflow
Solution 9 - Pythonhonederr82View Answer on Stackoverflow
Solution 10 - Pythonuser9311010View Answer on Stackoverflow