获取 .wav 文件长度或持续时间

发布于 2024-12-11 05:59:55 字数 194 浏览 0 评论 0 原文

我正在寻找一种方法来找出 python 中音频文件(.wav)的持续时间。到目前为止,我查看了 python wave 库、mutagenpymediapymad 我无法得到wav 文件的持续时间。 Pymad 给了我持续时间,但它不一致。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

寂寞美少年 2024-12-18 05:59:55

持续时间等于帧数除以帧速率(每秒帧数):

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)

关于 @edwards 的评论,这里有一些生成 2 通道波形文件的代码:

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

如果您在音频播放器中播放生成的文件,您会发现持续时间是 40 秒。如果运行上面的代码,它还会计算出持续时间为 40 秒。所以我相信帧数不受通道数的影响,并且上面的公式是正确的。

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.

草莓酥 2024-12-18 05:59:55

librosa 库可以执行此操作: librosa

import librosa
librosa.get_duration(filename='my.wav')
# note that the 'filename' keyword argument was deprecated in version
# 0.10 and replaced with 'path'. A comment in the source code says 'filename' will be removed in version 1.0

the librosa library can do this: librosa

import librosa
librosa.get_duration(filename='my.wav')
# note that the 'filename' keyword argument was deprecated in version
# 0.10 and replaced with 'path'. A comment in the source code says 'filename' will be removed in version 1.0
皓月长歌 2024-12-18 05:59:55

一个非常简单的方法是使用 soundfile (以前的 pysoundfile)。

以下是如何执行此操作的一些示例代码:

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

该特定文件的输出是:

samples = 232569
sample rate = 16000
seconds = 14.5355625

这与 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

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
梦巷 2024-12-18 05:59:55

我们可以使用 ffmpeg 来获取任何视频或音频文件的持续时间。

要安装 ffmpeg,请点击此链接

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

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'])
大海や 2024-12-18 05:59:55
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()
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()
绾颜 2024-12-18 05:59:55

令 T 为两个连续样本之间的持续时间。因此,我们可以写成t = nTt = n/Fs

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

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 = len(data)
t = n / Fs
披肩女神 2024-12-18 05:59:55

我试图获取除“.wav”之外的不同格式的音频文件的长度,我尝试了上述一些解决方案,但对我不起作用

这对我有用:

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

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']
等往事风中吹 2024-12-18 05:59:55

要查找音乐文件的长度,可以使用audioread模块,

安装audioread:pip install audioread

然后使用以下代码:

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

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
北陌 2024-12-18 05:59:55

pydub 的另一个解决方案:

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

Another solution with pydub:

import pydub
audio_seg = AudioSegment.from_wav('mywav.wav')
total_in_ms = len(audio_seg)
瀟灑尐姊 2024-12-18 05:59:55

如果你的机器上安装了 mediainfo,你也可以使用类似这样的东西(Python 3):

from subprocess import check_output

def get_wav_duration(path):
    return int(check_output(
        f'mediainfo --Inform="Audio;%Duration%" {path}', shell=True))

返回的结果以毫秒为单位。

And if you have mediainfo installed on your machine, you can also use something like this (Python 3):

from subprocess import check_output

def get_wav_duration(path):
    return int(check_output(
        f'mediainfo --Inform="Audio;%Duration%" {path}', shell=True))

The returned result is given in milliseconds.

瞎闹 2024-12-18 05:59:55

您可以使用 soundfile.info

import soundfile as sf

info = sf.info("my_file.wav")
print(f"The file is {info.duration} seconds long")

info< /code> 对象还具有其他有用的属性,例如 channelssamplerateframes

要安装soundfile,请使用pip install soundfile

You can use soundfile.info:

import soundfile as sf

info = sf.info("my_file.wav")
print(f"The file is {info.duration} seconds long")

The info object also has other useful attributes like channels, samplerate, and frames.

To install soundfile, use pip install soundfile.

陈独秀 2024-12-18 05:59:55

它很短,不需要模块,适用于所有操作系统:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文