Excel VBAでファイル解析(MP3ファイル編)
■MP3ファイルの概要
MP3(MPEG-1 Audio Layer-3)は音響データの圧縮に関する規格の1つで、MP3で圧縮された音声データを格納しているファイルの拡張子は「.mp3」です。
MP3本体の規格は難易度が高いため、本稿ではID3タグを中心に記載します。
(参考)日本規格協会のサイトで以下の規格書を購入可能ですが、価格は28,314円(税込み)です。
- ISO/IEC 11172-3:1993
- 情報技術-1,5 Mbit/s以下のデジタル記録媒体のための映画及び関連オーディオの符号化-第3部:オーディオ
- Information technology — Coding of moving pictures and associated audio for digital storage media at up to about 1,5 Mbit/s — Part 3: Audio
ID3タグは、MP3ファイルの中にアーティスト・作成年・曲名等の付加的な情報を書き込むための規格ですが、v1とv2で規格の内容が大きく異なり、さらにv2の中にもv2.1、v2.2、v2.3、v2.4といったバージョンが存在します。
全てのバージョンに対応するのはなかなか大変なので、本稿ではv2.3とv2.4に限定したうえ、「アルバム名」「年」「トラック番号」「アーティスト名」「曲名」「添付画像」を取出すことに目的を絞って説明します。
⇒ID3タグの詳細はID3.orgのサイト(id3 v2.3.0、id3 v2.4.0)を参照して下さい。
ID3v2タグの詳細
ID3v2タグはMP3ファイルの先頭にあり、下表の通り、ID3v2ヘッダ、拡張ヘッダ、フレームデータから構成されています。
ID3v2ヘッダと拡張ヘッダは1つだけ存在しますが、フレームデータは複数存在し、フレームの種類によって格納されている内容が異なります。
ID3v2ヘッダ | |||||||||||
拡張ヘッダ | |||||||||||
フレームデータ | |||||||||||
TALB(Album/Movie/Show title) | |||||||||||
TYER(Year) | |||||||||||
TRCK(Track number/Position in set) | |||||||||||
TPE1(Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group) | |||||||||||
TIT2(Title/songname/content description) | |||||||||||
APIC(Attached picture) |
ID3v2ヘッダのフォーマット
ID3v2ヘッダは10バイト固定となっており、内容は下表の通りです。
オフセット | 長さ | 説明 |
---|---|---|
0 | 3 | マジックナンバー (“ID3″固定) |
3 | 2 | バージョン (v2.3:0300、v2.4:0400) |
5 | 1 | フラグ (左から2ビット目が1の時、拡張ヘッダ有) |
6 | 4 | サイズ(※) (ID3タグ全体の長さ – 10バイト) |
(※)ID3タグの数値はビッグ・エンディアン(MSB(最上位バイト) first)で格納されていますが、v2.4ではSyncsafe Integerと呼ばれる「各バイトの下位7bit のみが有効となっている形式」になっているため、注意が必要です。
例えば、4バイトの「サイズ」を1バイトずつ取り出して計算する場合、v2.3とv2.4で下図のように計算方法が異なります。
- (v2.3) サイズ = 1バイト目 * 16777216 + 2バイト目 * 65536 + 3バイト目 * 256 + 4バイト目
- (v2.4) サイズ = 1バイト目 * 2097152 + 2バイト目 * 16384 + 3バイト目 * 128 + 4バイト目
拡張ヘッダのフォーマット
拡張ヘッダのフォーマットは、v2.3とv2.4で異なっており、内容は下表の通りです。
(拡張ヘッダ(v2.3))
オフセット | 長さ | 説明 |
---|---|---|
0 | 4 | この拡張ヘッダのサイズ |
4 | 2 | フラグ |
6 | 4 | パディング領域のサイズ |
10 | 可変長 | 拡張ヘッダのデータ |
(拡張ヘッダ(v2.4))
オフセット | 長さ | 説明 |
---|---|---|
0 | 4 | この拡張ヘッダのサイズ |
4 | 1 | フラグ長(常に1) |
5 | 1 | フラグ |
6 | 可変長 | 拡張ヘッダのデータ |
各フレームの共通フォーマット
各フレームは下表の形式になっており、「フレームID」「フレームサイズ」「フラグ」を合せてフレームヘッダと呼びます。
(フレームヘッダは10バイト固定です)
オフセット | 長さ | 説明 |
---|---|---|
0 | 4 | フレームID (種別1バイト + ネーム3バイト) |
4 | 4 | フレームサイズ (フレームデータ全体の長さ – 10バイト) |
8 | 2 | フレームヘッダフラグ (1バイト目:ステータス、2バイト目:フォーマット) |
10 | 可変長 | フレームデータ (フレームID毎に内容が異なる) |
テキスト情報フレームのフォーマット
データをテキストで保有するフレーム(Text information frames)のフレームデータは、下表の形式になっています。
本稿で取り上げるフレームのうち、「アルバム名(TALB)」「年(TYER)」「トラック番号(TRCK)」「アーティスト名(TPE1)」「曲名(TIT2)」は、この形式です。
オフセット | 長さ | 説明 |
---|---|---|
0 | 1 | エンコーディング 00h:ISO-8859-1 01h:UTF-16/BOMあり 02h:UTF-16BE/BOMなし(id3v2.4) 03h:UTF-8(id3v2.4) |
1 | 可変長 | フレーム内容 (NULL終端テキスト) 終端文字は以下のいずれか “00h"(ISO-8859-1,UTF-8) “00h 00h"(UTF-16) |
添付画像フレームのフォーマット
画像データを保有するフレーム(Attached picture frame)のフレームデータは、下表の形式になっています。
本稿で取り上げるフレームのうち、「添付画像(APIC)」は、この形式です。
オフセット | 長さ | 説明 |
---|---|---|
0 | 1 | Text encoding |
1 | 可変長 | MIME type(NULL終端テキスト) |
可変 | 1 | Picture type(下表参照) |
可変 | 可変長 | Description(NULL終端テキスト) |
可変 | 可変長 | Picture data(バイナリ・データ) |
(Picture type)
値 | 内容 |
---|---|
00 | Other |
01 | 32×32 pixels 'file icon'(PNG only) |
02 | Other file icon |
03 | Cover(front) |
04 | Cover(back) |
05 | Leaflet page |
06 | Media(e.g. lable side of CD) |
07 | Lead artist/lead performer/soloist |
08 | Artist/performer |
09 | Conductor |
0A | Band/Orchestra |
0B | Composer |
0C | Lyricist/text writer |
0D | Recording Location |
0E | During recording |
0F | During performance |
10 | Movie/video screen capture |
11 | A bright coloured fish |
12 | Illustration |
13 | Band/artist logotype |
14 | Publisher/Studio logotype |
■MP3ファイルのID3タグ情報をExcelシートに表示する処理
MP3ファイルのID3タグ情報を読み込み、Excelシートに表示するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。
処理の概要
処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、MP3ファイルを読み込み
②MP3ファイルのID3タグを先頭から順に解析し、必要な情報を取得してExcelシートにセット
③使用済のオブジェクトを破棄
サンプル・プログラム
行番号10でBinary Fileオブジェクトをインスタンス化し、行番号11でMP3ファイルを読み込んでいます。
行番号14~37はID3v2ヘッダの処理で、「ファイル識別子」「バージョン」「フラグ」「サイズ」を取得しています。
行番号39~51は拡張ヘッダの処理で、拡張ヘッダが存在した場合は読み飛ばしています。
行番号53~87はフレームデータの処理で、行番号65~69で「アルバム名」「アーティスト名」「曲名」、行番号71~75で「年」「トラック番号」、行番号77~83で「添付画像」のデータを取得し、行番号85でそれ以外のフレームを読み飛ばしています。
行番号81のGetDataNullメソッドで取得しているデータは、前掲した表の「MIME type」という項目ですが、実際には『image/jpeg』のような文字列が入っています。
(注)テキスト情報については、エンコードの値によって処理を分けるのが本来の姿ですが、このサンプル・プログラムでは「アルバム名」「アーティスト名」「曲名」をUTF-16、「年」「トラック番号」をISO-8859-1として処理しています。
「アルバム名」「アーティスト名」「曲名」がUTF-8で格納されている場合は、行番号69のGetDataUTF16メソッドをGetDataUTF8メソッドに置換えて下さい。
(補記)wcntはGetDataNullメソッドの引数に使用している変数ですが、行番号3で他の変数と一緒に定義しておいたところ、実行時にエラーが発生したため、行番号4で「Dim wcnt As Long」と定義したものです。
- Dim sht, bf As Object
- Dim wVer, wStr As String
- Dim wLoc, wID, wSize, wExtSize, wLen, i, lcnt As Long
- Dim wcnt As Long
- Dim wFlag As Byte
- Private Sub Sample1()
- Set sht = ActiveSheet
- sht.Cells.NumberFormatLocal = “@"
- Set bf = New BinaryFile
- bf.InputFile (“C:\work\xxx.mp3")
- lcnt = 0
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = bf.GetPositionHex()
- sht.Cells(lcnt, 2) = “ファイル識別子"
- sht.Cells(lcnt, 3) = bf.GetDataChar(3)
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = bf.GetPositionHex()
- sht.Cells(lcnt, 2) = “バージョン"
- wVer = bf.GetDataHex(2)
- sht.Cells(lcnt, 3) = wVer
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = bf.GetPositionHex()
- sht.Cells(lcnt, 2) = “フラグ"
- wFlag = bf.GetData(1)
- sht.Cells(lcnt, 3) = Right(“0" & Hex(wFlag), 2)
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = bf.GetPositionHex()
- sht.Cells(lcnt, 2) = “サイズ"
- wStr = bf.GetDataHex(4)
- sht.Cells(lcnt, 3) = wStr
- If wVer = “0400" Then
- wSize = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wSize = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- If (wFlag And &H40) = &H40 Then
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = bf.GetPositionHex()
- sht.Cells(lcnt, 2) = “拡張ヘッダサイズ"
- wStr = bf.GetDataHex(4)
- sht.Cells(lcnt, 3) = wStr
- If wVer = “0400" Then
- wExtSize = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wExtSize = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- bf.SkipData (wExtSize – 4)
- End If
- Do While bf.CurrentPosition < wSize + 10
- wLoc = bf.GetPositionHex()
- wID = bf.GetDataChar(4)
- wStr = bf.GetDataHex(4)
- If wVer = “0400" Then
- wLen = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wLen = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- bf.SkipData (2)
- Select Case wID
- Case “TALB", “TPE1", “TIT2"
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = wLoc
- sht.Cells(lcnt, 2) = wID
- bf.SkipData (1)
- sht.Cells(lcnt, 3) = bf.GetDataUTF16(CLng(wLen) – 1)
- Case “TYER", “TRCK"
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = wLoc
- sht.Cells(lcnt, 2) = wID
- bf.SkipData (1)
- sht.Cells(lcnt, 3) = bf.GetDataChar(CLng(wLen) – 1)
- Case “APIC"
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = wLoc
- sht.Cells(lcnt, 2) = wID
- bf.SkipData (1)
- sht.Cells(lcnt, 3) = bf.GetDataNull(wcnt)
- sht.Cells(lcnt, 4) = bf.GetDataHex(1)
- bf.SkipData (CLng(wLen) – wcnt – 1)
- Case Else
- bf.SkipData (CLng(wLen))
- End Select
- Loop
- Set bf = Nothing
- End Sub
■MP3ファイルのID3タグ情報から画像データを抽出する処理
MP3ファイルのID3タグ情報を読み込み、画像データをファイルに出力するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。
処理の概要
処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、MP3ファイルを読み込み
②MP3ファイルのID3タグを先頭から順に解析し、画像データを取得してファイルに出力
③使用済のオブジェクトを破棄
サンプル・プログラム
行番号9でBinary Fileオブジェクトをインスタンス化し、行番号10でMP3ファイルを読み込んでいます。
行番号13~21はID3v2ヘッダの処理で、「ファイル識別子」「バージョン」「フラグ」「サイズ」を取得しています。
行番号23~31は拡張ヘッダの処理で、拡張ヘッダが存在した場合は読み飛ばしています。
行番号33~51はフレームデータの処理で、行番号43~47で「添付画像」のフレームを処理し、行番号49で他のフレームを読み飛ばしています。
行番号46のTransferDataメソッドでバイナリ・データを出力エリアに転送し、行番号47のOutputFileメソッドでJPEGファイルを出力しています。
「添付画像」のフレーム(フレームID:APIC)の場合、規格上は「Picture Type」の後ろに「Description」を設定できますが、このサンプル・プログラムでは「Description」が存在しない前提で処理しています。
- Dim sht, bf As Object
- Dim wVer, wStr As String
- Dim wLoc, wID, wSize, wExtSize, wLen, wPos, i, lcnt As Long
- Dim wcnt As Long
- Dim wFlag As Byte
- Private Sub Sample2()
- Set sht = ActiveSheet
- Set bf = New BinaryFile
- bf.InputFile (“C:\work\xxx.mp3")
- lcnt = 0
- wStr = bf.GetDataChar(3)
- wVer = bf.GetDataHex(2)
- wFlag = bf.GetData(1)
- wStr = bf.GetDataHex(4)
- If wVer = “0400" Then
- wSize = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wSize = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- If (wFlag And &H40) = &H40 Then
- wStr = bf.GetDataHex(4)
- If wVer = “0400" Then
- wExtSize = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wExtSize = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- bf.SkipData (wExtSize – 4)
- End If
- Do While bf.CurrentPosition < wSize + 10
- wID = bf.GetDataChar(4)
- wStr = bf.GetDataHex(4)
- If wVer = “0400" Then
- wLen = CLng(“&H" & Mid(wStr, 1, 2)) * 2097152 + CLng(“&H" & Mid(wStr, 3, 2)) * 16384 + CLng(“&H" & Mid(wStr, 5, 2)) * 128 + CLng(“&H" & Mid(wStr, 7, 2))
- Else
- wLen = CLng(“&H" & Mid(wStr, 1, 2)) * 16777216 + CLng(“&H" & Mid(wStr, 3, 2)) * 65536 + CLng(“&H" & Mid(wStr, 5, 2)) * 256 + CLng(“&H" & Mid(wStr, 7, 2))
- End If
- bf.SkipData (2)
- If wID = “APIC" Then
- bf.SkipData (1)
- wStr = bf.GetDataNull(wcnt)
- bf.SkipData (2)
- bf.TransferData (wLen – wcnt – 2)
- bf.OutputFile (“C:\work\xxx.jpg")
- Else
- bf.SkipData (CLng(wLen))
- End If
- Loop
- Set bf = Nothing
- End Sub
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ
ディスカッション
コメント一覧
MP3のメタデータ編集を実装しようとして本記事に辿り着きました。
APICの(Picture type) の仕様は一般的に知られている規格なのでしょうか?
検索で探すことができず仕様が把握できなかったため、もし公式ドキュメント的なものがあるのであればURLを教えていただけないでしょうか。
コメントありがとうございます。
お問合せの件ですが、ID3.orgのサイトで公開されているID3v2.4の仕様書(→https://id3.org/id3v2.4.0-frames)が参考になると思いますので、アクセスしてみて下さい。
ありがとうございます!
4.14. Attached picture の章に書いてあるのが確認できました。