MP3文件格式全解
mp3播放參考代碼(libmad庫):my_minimad
wav播放參考代碼(alsa聲卡,alsa-lib庫):wav_miniplay
WAV 格式文件頭(除了文件頭就是音頻數據了),很簡單,不用多說
struct WAVFmtHeader {char strRIFF[4]; /* 'RIFF' 資源文件標志,固定字符 */unsigned long dwTotalByte; /* 從下一個成員開始到文件結尾的總字節數 */char strWAVE[4]; /* 'WAVE' 表示是 WAVE 文件,固定字符 */char strFmt[4]; /* 'fmt ' 波形格式標志,固定字符 */unsigned long dwPcmFmt; /* 數據格式 16LE,32LE等等 */unsigned short bIsCompress; /* 是否是壓縮的 PCM 編碼,大于 1 表示有壓縮,等于 1 表示無壓縮 */unsigned short wChannels; /* 聲道數量 */unsigned long dwPcmSampRate; /* 采樣頻率 */unsigned long dwByteRate; /* byte 率, byterate = 采樣頻率 * 音頻通道數量 * 數據位數 / 8 */unsigned short wFrameSize; /* 塊對齊/幀大小 framesize = 通道數 * 數據位數 / 8 */unsigned short wSampBitWidth; /* 樣本數據位數 */char strData[4]; /* 'data' 數據標志,固定字符 */unsigned long dwPcmDataSize; /* 實際音頻數據的大小 */ };1. MP3 全稱
- MP3 全稱是 MPEG1 PlayerIII 音頻文件
- MPEG (Moving Picture Experts Group) 動態圖像專家組,也就是為圖像制作標準的組織,由 1988 年成立
- 根據壓縮的復雜度分為 PlayerI PlayerII 與 PlayerIII,復雜程度依次遞增
2. MP3 文件的組成
MP3 文件的最小組成單位是幀。
2.1 ID3vX
ID3vX 是一種標簽,在 MP3 文件中也以幀的形式存在,不過并不是 MP3 文件的有效音頻數據幀,而是一個標簽,里面包含有歌曲信息,例如:作曲人,歌曲制作時間等等
- ID3v1
第一個版本的音頻標簽,長度為固定的 128 字節,位置在 MP3 文件的尾部。(事實上我看了很多的 MP3 文件,尾部并沒有這個標簽幀,這點存在疑惑)
ID3v1 標簽幀的數據格式如下所示:
char Header[3]; /* 標簽頭必須是"TAG"否則認為沒有標簽 */ char Title[30]; /* 標題 */ char Artist[30]; /* 作者 */ char Album[30]; /* 專輯 */ char Year[4]; /*出品年代*/ char Comment[30]; /*備注*/ char Genre; /*類型*/其數據存放按照順序一個個存放,如果長度不足則補 0,ID3v1 應該已經比較少用了
- ID3v2.3
ID3v2 其實有 4 個版本,但是常用的只有 2.3 這個版本,所以這里只記錄 2.3 版本的信息
ID3v2.3 有標簽頭和標簽幀,標簽頭記錄版本以及整個 ID3v2.3 的大小,標簽幀則是記錄歌曲信息
ID3v2.3 在文件的開頭存放,從第一個字節開始,整個 ID3v2 的結構圖如下所示
ID3v2 的結構圖表
| 標簽頭 | ID3v2標識 | 3 | 固定字符 “ID3” ,表示是 ID3v2 標簽 |
| ID3v2子版本號 | 2 | 03H 00H 表示是 ID3v2.3 | |
| ID3v2標志 | 1 | abc00000B a 非同步編碼 b 擴展標簽頭 c 測試指示為,都是 1 有效,一般都是 0 | |
| ID3v2大小 | 4 | 只有后 7 位有效,size = byteA:7 * 0x200000 + byteB:7 * 0x4000 + byteC:7 * 0x80 + byteD:7 | |
| 擴展標簽頭 | 擴展標簽頭大小 | 4 | size = byte0 * 0x200000 + byte1 * 0x4000 + byte2 * 0x80 + byte3 |
| 擴展標志 | 2 | xx | |
| 補空大小 | 4 | 你可以在所有的標簽幀后面添加補空數據,也可以預留空間存放額外的幀,使得整個標簽大小比標簽頭中的大小要更大,這里記錄的就是增加的大小,一般不用 | |
| 標簽幀 | 幀標識 | 4 | 固定的 4 個字符,用來標識這一幀里面存放的內容是什么,標識見下面的對照表:標簽幀的標識以及其意義對照表 |
| 幀大小 | 4 | size = byte0 * 0x200000 + byte1 * 0x4000 + byte2 * 0x80 + byte3 | |
| 標志 | 2 | 不重要 | |
| 幀數據 | size | 存放的數據 | |
| … | … | … | … |
| 補空 | 補空大小 | 00H … |
2.2 CBR 與 VBR
- CBR :幀長度固定,也就是說每一幀的播放時間是固定的,知道了一幀的長度以及文件的大小就可以計算出整個播放時長
- VBR :幀長不固定,要獲得整個播放時長需要知道文件一共有多少幀
幀長計算公式
LayerII 與 LayerII
幀長 = (每幀采樣次數 * 比特率 / 8 / 采樣率) + 補白
LayerI
幀長 = (每幀采樣次數 * 比特率 / 8 / 采樣率) + 補白 * 4
CBR 總播放時長計算公式
播放時長 = (文件大小 – ID3標簽大小) * 8 / 比特率
VBR 總播放時長計算公式
播放時長 = 有效數據幀總幀數 * 每幀采樣數 / 采樣率
每幀數據的采樣數索引表:每幀數據的采樣數表
每一幀的播放時長計算公式
幀播放時長 = 采樣數 / 采樣頻率 * 1000 毫秒
事實上 windows 上面我看到的都是按照 CBR 格式計算時長的,所以采用 CBR 格式計算即可
2.3 有效數據幀
所有的有效數據幀都有幀頭,幀頭為 4 個字節,它們的含義如下所示
有效數據幀幀頭
| 0 | 11 | 幀同步標識,表示數據幀一幀的開始 |
| 11 | 2 | MPEG 音頻版本號,參照表:MPEG 音頻版本表 |
| 13 | 2 | Layer 版本,參照表:Layer 索引表 |
| 15 | 1 | 保護位,0 - 16bit CRC 0 - 無 CRC |
| 16 | 4 | 比特率索引,參照表:比特率索引表(單位-Kbps) |
| 20 | 2 | 采樣率索引,參照表:采樣率索引表 |
| 22 | 1 | 如果設置的話數據被補空為一個 slot,LayerI slot 是 4 字節,其余為 1 字節 |
| 23 | 1 | 私有位 |
| 24 | 2 | channel 模式,參照表:channel 模式表 |
| 26 | 2 | 模式擴展 |
| 28 | 1 | Copyright 位 |
| 29 | 1 | Original 位 |
| 30 | 2 | 強調,不關注 |
結構體可定義為如下所示:
struct DataFrameHeader {unsigned int bzFrameSyncFlag1:8; /* 全為 1 */unsigned int bzProtectBit:1; /* CRC */unsigned int bzVersionInfo:4; /* 包括 mpeg 版本,layer 版本 */unsigned int bzFrameSyncFlag2:3; /* 全為 1 */unsigned int bzPrivateBit:1; /* 私有 */unsigned int bzPaddingBit:1; /* 是否填充,1 填充,0 不填充layer1 是 4 字節,其余的都是 1 字節 */unsigned int bzSampleIndex:2; /* 采樣率索引 */unsigned int bzBitRateIndex:4; /* bit 率索引 */unsigned int bzExternBits:6; /* 版權等,不關心 */ unsigned int bzCahnnelMod:2; /* 通道* 00 - Stereo 01 - Joint Stereo* 10 - Dual 11 - Single*/ };VBR 有效數據幀
由于市面上大多數 MP3 壓縮都是用的 LAME 公司的技術,所以只講 LAME 公司,”Info” 與 “Xing” 都是 LAME 公司的數據壓縮標識
采用 VBR 編碼的音頻數據在有效數據幀的第一幀會有一個 VBR 頭,且只有第一幀有,頭部標識為 “Xing”。數據幀的第一幀包涵了整個 MP3 文件的信息,幀頭是 4 個字節,接著是 32 字節的 0 填充,然后是 “Info” 或者 “Xing” 字符標識
此 VBR 頭在上面有效數據幀幀頭之后偏移 32 字節的位置,數據格式如下
VBR 頭
| 0 | 4 | 固定的 ‘Xing’ or ‘Info’ |
| 4 | 4 | 不關注 |
| 8 | 4 | 幀數量,大端存儲 |
| 8 or 12 | 4 | 字節數,大端存儲 |
| 8, 12 or 16 | 100 | 100 個時間點索引,例如一段音頻長 3 分鐘,分成 100 份,記錄每一段的起始位置 |
| 8, 12, 16, 108, 112, 116 | 4 | 不關注 |
3. MP3 文件的內容排列
ID3v2 如果有的話 補空 如果有 ID3V2 VBR幀(有效數據幀第一幀) 如果是 VBR 編碼的話 有效數據幀 一定有 ID3v1 一定有(大多數地方寫的),我看到的就沒有MPEG 音頻版本表
| 00 | MPEG 2.5 |
| 01 | reserved |
| 10 | MPEG 2 |
| 11 | MPEG 1 |
Layer 索引表
| 00 | reserved |
| 01 | LayerIII |
| 10 | LayerII |
| 11 | LayerI |
比特率索引表(單位 Kbps)
| Bitrate Index | MPEG 1 | MPEG 2,2.5 | ||||
| LayerI | LayerII | LayerIII | LayerI | LayerII & LayerIII | ||
| 0000 | ||||||
| 0001 | 32 | 32 | 32 | 32 | 8 | |
| 0010 | 64 | 48 | 40 | 48 | 16 | |
| 0011 | 96 | 56 | 48 | 56 | 24 | |
| 0100 | 128 | 64 | 56 | 64 | 32 | |
| 0101 | 160 | 80 | 64 | 80 | 40 | |
| 0110 | 192 | 96 | 80 | 96 | 48 | |
| 0111 | 224 | 112 | 96 | 112 | 56 | |
| 1000 | 256 | 128 | 112 | 128 | 64 | |
| 1001 | 288 | 160 | 128 | 144 | 80 | |
| 1010 | 320 | 192 | 160 | 160 | 96 | |
| 1011 | 352 | 224 | 192 | 176 | 112 | |
| 1100 | 384 | 256 | 224 | 192 | 128 | |
| 1101 | 416 | 320 | 256 | 224 | 144 | |
| 1110 | 448 | 384 | 320 | 256 | 160 | |
| 1111 |
采樣率索引表
| 00 | 44100 | 22050 | 11025 |
| 01 | 48000 | 24000 | 12000 |
| 10 | 32000 | 16000 | 8000 |
| 11 | reserved | reserved | reserved |
每幀數據的采樣數
| Layer I | 384 | 384 | 384 |
| Layer II | 1152 | 1152 | 1152 |
| Layer III | 1152 | 576 | 576 |
channel 模式表
| 00 | Stereo |
| 01 | Joint Stereo (Stereo) |
| 10 | Dual channel (Two mono channels) |
| 11 | Single channel (Mono) |
標簽幀的標識以及其意義對照表
| AENC | [Audio encryption] |
| APIC | [Attached picture] |
| COMM | [Comments] |
| COMR | [Commercial frame] |
| ENCR | [Encryption method registration] |
| EQUA | [Equalization] |
| ETCO | [Event timing codes] |
| GEOB | [General encapsulated object] |
| GRID | [Group identification registration] |
| IPLS | [Involved people list] |
| LINK | [Linked information] |
| MCDI | [Music CD identifier] |
| MLLT | [MPEG location lookup table] |
| OWNE | [Ownership frame] |
| PRIV | [Private frame] |
| PCNT | [Play counter] |
| POPM | [Popularimeter] |
| POSS | [Position synchronisation frame] |
| RBUF | [Recommended buffer size] |
| RVAD | [Relative volume adjustment] |
| RVRB | [Reverb] |
| SYLT | [Synchronized lyric/text] |
| SYTC | [Synchronized tempo codes] |
| TALB | [Album/Movie/Show title] |
| TBPM | [BPM (beats per minute)] |
| TCOM | [Composer] |
| TCON | [Content type] |
| TCOP | [Copyright message] |
| TDAT | [Date] |
| TDLY | [Playlist delay] |
| TENC | [Encoded by] |
| TEXT | [Lyricist/Text writer] |
| TFLT | [File type] |
| TIME | [Time] |
| TIT1 | [Content group description] |
| TIT2 | [Title/songname/content description] |
| TIT3 | [Subtitle/Description refinement] |
| TKEY | [Initial key] |
| TLAN | [Language(s)] |
| TLEN | [Length] |
| TMED | [Media type] |
| TOAL | [Original album/movie/show title] |
| TOFN | [Original filename] |
| TOLY | [Original lyricist(s)/text writer(s)] |
| TOPE | [Original artist(s)/performer(s)] |
| TORY | [Original release year] |
| TOWN | [File owner/licensee] |
| TPE1 | [Lead performer(s)/Soloist(s)] |
| TPE2 | [Band/orchestra/accompaniment] |
| TPE3 | [Conductor/performer refinement] |
| TPE4 | [Interpreted, remixed, or otherwise modified by] |
| TPOS | [Part of a set] |
| TPUB | [Publisher] |
| TRCK | [Track number/Position in set] |
| TRDA | [Recording dates] |
| TRSN | [Internet radio station name] |
| TRSO | [Internet radio station owner] |
| TSIZ | [Size] |
| TSRC | [ISRC (international standard recording code)] |
| TSSE | [Software/Hardware and settings used for |
| TYER | [Year] |
| TXXX | [User defined text information frame] |
| UFID | [Unique file identifier] |
| USER | [Terms of use] |
| USLT | [Unsychronized lyric/text transcription] |
| WCOM | [Commercial information] |
| WCOP | [Copyright/Legal information] |
| WOAF | [Official audio file webpage] |
| WOAR | [Official artist/performer webpage] |
| WOAS | [Official audio source webpage] |
| WORS | [Official internet radio station homepage] |
| WPAY | [Payment] |
| WPUB | [Publishers official webpage] |
| WXXX | [User defined URL link frame] |
總結
- 上一篇: 清除微信公众号缓存方法(安卓手机+苹果手
- 下一篇: continue用法(continue用