WAV文件头不支持ID3等元数据标准,仅含技术参数;可选LIST/INFO块兼容性差,推荐用BEXT扩展或转FLAC/MP3格式处理元数据。

WAV文件头不是元数据容器,别往ID3方向想
WAV格式本身不支持ID3、XMP或嵌入式标签这类通用元数据标准。它的“头”是RIFF结构的固定二进制布局(RIFF chunk + fmt chunk + data chunk),只描述采样率、位深、声道数等技术参数,不存歌手、专辑名等信息。试图用C#往WAV头里写Title或Artist字段,本质是无效操作——播放器不会读,标准解析器也不认。
真要加元数据?只能靠LIST/INFO块(且兼容性极差)
少数WAV实现允许在LIST chunk中嵌套INFO子块,存放INAM(标题)、IART(艺术家)等8字节标识符+字符串。但这是非强制规范,Windows Media Player可能读,VLC常忽略,Audacity默认不显示。操作时必须:
- 严格按4字节对齐:每个字段值长度需补零至偶数,整个
INFOchunk大小必须是偶数字节 - 先定位到
LISTchunk(搜索LIST四字节+后续4字节size),再检查其type是否为INFO - 修改时不能破坏原有chunk顺序,否则
datachunk可能被解析器跳过
示例片段(读取INAM):
byte[] buf = File.ReadAllBytes("test.wav");
int listPos = FindChunk(buf, "LIST", 0);
if (listPos != -1 && BitConverter.ToUInt32(buf, listPos + 8) == BitConverter.ToUInt32(Encoding.ASCII.GetBytes("INFO"), 0))
{
int infoStart = listPos + 12;
int inamPos = FindSubchunk(buf, infoStart, "INAM");
if (inamPos != -1)
{
int len = BitConverter.ToUInt16(buf, inamPos + 4);
string title = Encoding.ASCII.GetString(buf, inamPos + 6, len).TrimEnd('\0');
}
}
生产环境推荐:转用BEXT或完全换格式
广播级WAV常用BEXT chunk(Broadcast Wave Format extension),它定义了标准化字段如description、originator、origination_date,多数专业音频工具(Adobe Audition、Sound Forge)支持。C#可用BinaryReader按BEXT规范偏移量提取:
-
description:偏移32,256字节ASCII -
origination_date:偏移540,10字节ASCII(YYYY-MM-DD) - 注意:BEXT必须紧跟
fmtchunk后,且自身size固定为602字节
更务实的做法是放弃WAV元数据幻想——导出为FLAC(支持Vorbis Comments)或MP3(ID3v2),用TagLib#库统一处理:
var file = TagLib.File.Create("track.flac");
file.Tag.Title = "New Title";
file.Save(); // 自动处理编码、帧对齐、CRC
读取基础音频参数:用WaveFormat类比手撕二进制更稳
获取采样率、位深度等信息,不必手动解析fmt chunk。.NET内置System.Media.SoundPlayer虽不暴露细节,但可配合BinaryReader安全读取前44字节:
- 跳过
RIFF和WAVE标识(0–7字节) -
fmtchunk size在8–11字节(通常16)→ fmt数据起始=12 - 采样率在
fmt块第20–23字节:BitConverter.ToInt32(buf, 20) - 位深在第34–35字节:
BitConverter.ToInt16(buf, 34)
关键陷阱:某些录音设备生成的WAV含fact chunk或额外扩展,导致fmt 不在固定位置。务必用FindChunk(buf, "fmt " )动态定位,而非硬编码偏移。










