Obtener .wav longitud o duración del archivo

Estoy buscando una manera de averiguar la duración de un archivo de audio (.wav) en python. Hasta ahora pymedia pymad un vistazo a wave biblioteca de wave Python, pymedia , pymad , pymad y no pude obtener la duración del archivo wav. Pymad me dio la duración pero no es consistente.

Gracias por adelantado.

La duración es igual al número de cuadros dividido por la tasa de cuadros (cuadros por segundo):

 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) 

En cuanto al comentario de @edwards, aquí hay un código para producir un archivo de onda de 2 canales:

 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() 

Si reproduce el archivo resultante en un reproductor de audio, encontrará que tiene una duración de 40 segundos. Si ejecuta el código anterior, también calcula la duración en 40 segundos. Así que creo que la cantidad de cuadros no está influenciada por la cantidad de canales y la fórmula anterior es correcta.

Un método muy simple es usar pysoundfile, https://github.com/bastibe/PySoundFile

Aquí hay un código de ejemplo de cómo hacer esto:

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

La salida para ese archivo en particular es:

 samples = 232569 sample rate = 16000 seconds = 14.5355625 

Esto se alinea con 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 

Podemos usar ffmpeg para obtener la duración de cualquier video o archivo de audio.

Para instalar ffmpeg sigue este enlace.

 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\d+?):(?P\d+?):(?P\d+\.\d+?),", stdout, 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() 

Esto es corto y no necesita módulos, funciona con todos los sistemas operativos:

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