wav文件提取音频数据_python

wav文件格式

首先需要知道wav文件格式:(10条消息) WAV文件格式详解_imxiangzi的专栏-CSDN博客_wav文件格式

1177848-20171012202504012-1615456423

简单来说wav文件分为三个区块

这里主要讲的是提取wav文件的data部分

观察数据在文件头的分段

untitled_thumb

当然由于每个wav文件的采样规格不一样,在data数据部分的分段(比如左声道右声道以及每个采样点的字节数)是不一样的

我们可以看到的是data部分每个sample占两个字节,另外需要注意data的数据sample部分是小端存储,这就意味着在每个sample内部的两个字节若要正确提取出来,需要是以字节为单位相反顺序提取的

wave模块

使用wave模块进行提取:wave — 读写WAV格式文件 — Python 3.10.2 文档

打开文件

f = wave.open("flag.wav","r")
print(f)
# <wave.Wave_read object at 0x0000012E10681C40>

相当于返回的是wave_read对象,里面包含了这个wav文件的所有数据

  • 读取nframes个帧数的帧
f.readframes(nframes)
  • 获取帧数
f.getnframes()
  • 获取声道数
f.getnchannels()
  • 获取帧速率
f.getframerate()
  • 获取比特宽度(每一帧的字节数),使用这个函数就可以验证一下之前图上所展示的data部分单个sample的字节长度
f.getsampwidth()
  • 提取data部分的数据
f.readframes(f.getnframes)

以Misc的一道题为例,需要提取wav文件的data部分,并根据音频高低转换为1和0

每四位十六进制(也就是每两位字节)为一个sample

代码实现

import wave
f = wave.open("flag.wav","r")
framers_data = f.readframes(f.getnframes()).hex()
bin_data = ''
for i in range(0,len(framers_data),4):
    data = framers_data[i:i+4]
    data = data[2:] + data[:2] # 由于是小端存储,所以需要以字节为单位倒序
    if int(data,16) > 20000:
        bin_data += "1"
    else:
        bin_data += "0"
f.close()
with open("result.txt","a+") as f:
    f.write(bin_data)
f.close()

参考文章

WAVE 文件格式分析 - 唐风思琪 - 博客园 (cnblogs.com)

wav文件格式分析与详解 - nigaopeng - 博客园 (cnblogs.com)

wav文件格式分析与详解 - nigaopeng - 博客园 (cnblogs.com)

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐