简体   繁体   中英

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.

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(len(f)))
print('sample rate = {}'.format(f.samplerate))
print('seconds = {}'.format(len(f) / 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'])
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()

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

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

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

Another solution with pydub:

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

To calculate the duration (for general),

find the length of the audio frames and divide it by its sample rate.

eg. in Python.

If audio = [1,2,3,4,5] where the length of the frame is 5 with a sample_rate = 44100.

duration = len(audio) / sample_rate

print(duration)

=> 0.00011337868480725624

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM