Excel VBAでファイル解析(WMAファイル編)
■WMAファイルの概要
WMA(Windows Media Audio)はMicrosoftが開発した音声データの圧縮符号化方式で、ファイルの拡張子は「.wma」です。
WMAファイルの内部形式は、ASF(Advanced Systems Format)という規格で定められていますので、次項でASFの仕様を説明します。
なお、ASFで定められている内容は多岐に亘りますので、本稿ではタグ情報(「アルバム名」「年」「トラック番号」「アーティスト名」「曲名」「添付画像」)を取出すことに目的を絞って説明します。
WMAファイルの仕様
WMAファイルはObjectの集合体となっており、さまざまなObjectが定義されています。
Objectの基本構造は以下の通りシンプルな形式になっており、先頭にある「Object GUID」でオブジェクトを識別可能ですが、Objectの種類毎に「Object Data」の内容が異なるため、ファイルの中身を解析するためにはObjectの種類や構造を意識する必要があります。
(Objectの基本構造)
オフセット | 長さ | 説明 |
---|---|---|
0 | 16 | Object GUID(Globally Unique IDentifier) |
16 | 8 | Object Size |
24 | 可変長 | Object Data |
ASFの規格で定められているObjectの種類は、下表の通りです。
⇒詳細はMicrosoftのサイト(ASF(Advanced Systems Format))を参照して下さい。
(Objectの種類)
Object | GUID | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
top-level Header Object | ||||||||||||
Header Object | 75B22630-668E-11CF-A6D9-00AA0062CE6C | |||||||||||
File Properties Object | 8CABDCA1-A947-11CF-8EE4-00C00C205365 | |||||||||||
Stream Properties Object | B7DC0791-A9B7-11CF-8EE6-00C00C205365 | |||||||||||
Header Extension Object | 5FBF03B5-A92E-11CF-8EE3-00C00C205365 | |||||||||||
Extended Stream Properties Object | 14E6A5CB-C672-4332-8399-A96952065B5A | |||||||||||
Advanced Mutual Exclusion Object | A08649CF-4775-4670-8A16-6E35357566CD | |||||||||||
Group Mutual Exclusion Object | D1465A40-5A79-4338-B71B-E36B8FD6C249 | |||||||||||
Stream Prioritization Object | D4FED15B-88D3-454F-81F0-ED5C45999E24 | |||||||||||
Bandwidth Sharing Object | A69609E6-517B-11D2-B6AF-00C04FD908E9 | |||||||||||
Language List Object | 7C4346A9-EFE0-4BFC-B229-393EDE415C85 | |||||||||||
Metadata Object | C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA | |||||||||||
Metadata Library Object | 44231C94-9498-49D1-A141-1D134E457054 | |||||||||||
Index Parameters Object | D6E229DF-35DA-11D1-9034-00A0C90349BE | |||||||||||
Media Object Index Parameters Object | 6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7 | |||||||||||
Timecode Index Parameters Object | F55E496D-9797-4B5D-8C8B-604DFE9BFB24 | |||||||||||
Compatibility Object | 75B22630-668E-11CF-A6D9-00AA0062CE6C | |||||||||||
Advanced Content Encryption Object | 43058533-6981-49E6-9B74-AD12CB86D58C | |||||||||||
Codec List Object | 86D15240-311D-11D0-A3A4-00A0C90348F6 | |||||||||||
Script Command Object | 1EFB1A30-0B62-11D0-A39B-00A0C90348F6 | |||||||||||
Marker Object | F487CD01-A951-11CF-8EE6-00C00C205365 | |||||||||||
Bitrate Mutual Exclusion Object | D6E229DC-35DA-11D1-9034-00A0C90349BE | |||||||||||
Error Correction Object | 75B22635-668E-11CF-A6D9-00AA0062CE6C | |||||||||||
Content Description Object | 75B22633-668E-11CF-A6D9-00AA0062CE6C | |||||||||||
Extended Content Description Object | D2D0A440-E307-11D2-97F0-00A0C95EA850 | |||||||||||
Stream Bitrate Properties Object | 7BF875CE-468D-11D1-8D82-006097C9A2B2 | |||||||||||
Content Branding Object | 2211B3FA-BD23-11D2-B4B7-00A0C955FC6E | |||||||||||
Content Encryption Object | 2211B3FB-BD23-11D2-B4B7-00A0C955FC6E | |||||||||||
Extended Content Encryption Object | 298AE614-2622-4C17-B935-DAE07EE9289C | |||||||||||
Digital Signature Object | 2211B3FC-BD23-11D2-B4B7-00A0C955FC6E | |||||||||||
Padding Object | 1806D474-CADF-4509-A4BA-9AABCB96AAE8 | |||||||||||
top-level Data Object | ||||||||||||
Data Object | 75B22636-668E-11CF-A6D9-00AA0062CE6C | |||||||||||
top-level index objects | ||||||||||||
top-level Simple Index Object | 33000890-E5B1-11CF-89F4-00A0C90349CB | |||||||||||
top-level Index Object | D6E229D3-35DA-11D1-9034-00A0C90349BE | |||||||||||
top-level Media Object Index Object | FEB103F8-12AD-4C64-840F-2A1D2F7AD48C | |||||||||||
top-level Timecode Index Object | 3CB73FD0-0C4A-4803-953D-EDF7B6228F0C |
タグ情報は「Content Description Object」と「Extended Content Description Object」の中に保有していますので、次項で詳細を説明します。
Content Description Objectのフォーマット
Content Description Objectのフォーマットは、下表の通りです。
数値項目はリトル・エンディアンで格納されているため、エンディアン変換が必要になります。
「Object ID(GUID)」は16バイトですが、「Int32, Int16, Int16, Byte, Byte, Byte, Byte, Byte, Byte, Byte, Byte」という内訳になっているため、最初の4バイト、次の2バイト、その次の2バイトはエンディアン変換が必要ですが、残りの8バイトはエンディアン変換を行ってはいけません。
「Title」「Author」「Copyright」「Description」「Rating」はテキスト・データですが、ASFの仕様書には以下の記載がありますので、サンプル・プログラムではUTF-16として処理しています。
- WCHARの配列を指定します。
この文字列にnul-terminatorを含めることを強くお勧めしますが、
nul-terminatorが存在しない場合があります。
(Content Description Objectのフォーマット)
オフセット | 長さ | 説明 |
---|---|---|
0 | 16 | Object ID |
16 | 8 | Object Size |
24 | 4 | Title Length(Titleの長さ) |
28 | 4 | Author Length(Authorの長さ) |
32 | 4 | Copyright Length(Copyrightの長さ) |
36 | 4 | Description Length(Descriptionの長さ) |
40 | 4 | Rating Length(Ratingの長さ) |
可変 | 可変長 | Title(「曲名」) |
可変 | 可変長 | Author(「アーティスト名」) |
可変 | 可変長 | Copyright |
可変 | 可変長 | Description |
可変 | 可変長 | Rating |
Extended Content Description Objectのフォーマット
Extended Content Description Objectのフォーマットは、下表の通りです。
(Extended Content Description Objectのフォーマット)
オフセット | 長さ | 説明 |
---|---|---|
0 | 16 | Object ID |
16 | 8 | Object Size |
24 | 2 | Content Descriptors Count (Content Descriptorの個数) |
26 | 可変長 | Content Descriptors(下表参照) |
(Content Descriptorsのフォーマット)
オフセット | 長さ | 説明 |
---|---|---|
0 | 2 | Descriptor Name Length (Descriptor Nameの長さ) |
2 | 可変長 | Descriptor Name |
可変 | 2 | Descriptor Value Data Type(下表参照) |
可変 | 2 | Descriptor Value Length (Descriptor Valueの長さ) |
可変 | 可変長 | Descriptor Value |
(Descriptor Value Data Type)
値 | 長さ | タイプ |
---|---|---|
0x0000 | 可変 | Unicode string |
0x0001 | 可変長 | BYTE array |
0x0002 | 4 | BOOL |
0x0003 | 4 | DWORD |
0x0004 | 8 | QWORD |
0x0005 | 2 | WORD |
■WMAファイルのタグ情報をExcelシートに表示する処理
WMAファイルのタグ情報を読み込み、Excelシートに表示するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。
処理の概要
処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、WMAファイルを読み込み
②WMAファイルのタグ情報を解析し、必要な情報を取得してExcelシートにセット
③使用済のオブジェクトを破棄
サンプル・プログラム
行番号15でBinary Fileオブジェクトをインスタンス化し、行番号16でWMAファイルを読み込んでいます。
行番号19~74の繰返し処理のうち、行番号27はHeader Object、行番号30~41はContent Description Object、行番号44~70はExtended Content Encryption Object、行番号72はそれ以外のObjectの処理です。
タグ情報の表示については、行番号35~37で「曲名」、行番号38~40で「アーティスト名」、行番号50~54で「アルバム名」「年」「トラック番号」、行番号57~62で「添付画像」に関する処理を行っています。
(注)以下のプログラムは、テキスト情報がUTF-16で格納されているものとして処理を記述していますが、UTF-8で格納されている場合は、GetDataUTF16メソッドをGetDataUTF8メソッドに置換えて下さい。
- Dim sht, bf As Object
- Dim wLoc, wLen, wGUID, DescriptorName As String
- Dim EntNum, lcnt, i As Long
- Dim TitleLength As Long
- Dim AuthorLength As Long
- Dim CopyrightLength As Long
- Dim DescriptionLength As Long
- Dim DescriptorValueLength As Long
- Dim RatingLength As Long
- Dim DescriptorNameLength As Long
- Dim JpegLength As Long
- Private Sub Sample1()
- Set sht = ActiveSheet
- Set bf = New BinaryFile
- bf.InputFile (“C:\work\xxx.wma")
- lcnt = 0
- Do While bf.CurrentPosition < bf.FileSize
- wLoc = bf.GetPositionHex
- wGUID = bf.ConvertEndian(bf.GetDataHex(4)) & “-" & bf.ConvertEndian(bf.GetDataHex(2)) & “-" & bf.ConvertEndian(bf.GetDataHex(2)) & “-" & bf.GetDataHex(2) & “-" & bf.GetDataHex(6)
- wLen = bf.ConvertEndian(bf.GetDataHex(4))
- bf.SkipData (4)
- Select Case wGUID
- 'Header Object
- Case “75B22630-668E-11CF-A6D9-00AA0062CE6C"
- bf.SkipData (6)
- 'Content Description Object
- Case “75B22633-668E-11CF-A6D9-00AA0062CE6C"
- TitleLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- AuthorLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- CopyrightLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- DescriptionLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- RatingLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = “Title"
- sht.Cells(lcnt, 2) = bf.GetDataUTF16(TitleLength)
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = “Author"
- sht.Cells(lcnt, 2) = bf.GetDataUTF16(AuthorLength)
- bf.SkipData (CopyrightLength + DescriptionLength + RatingLength)
- 'Extended Content Encryption Object
- Case “D2D0A440-E307-11D2-97F0-00A0C95EA850"
- EntNum = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- For i = 1 To EntNum
- DescriptorNameLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- DescriptorName = bf.GetDataUTF16(DescriptorNameLength – 2)
- Select Case DescriptorName
- Case “WM/AlbumTitle", “WM/Year", “WM/TrackNumber"
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = Mid(DescriptorName, 4)
- bf.SkipData (4)
- DescriptorValueLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- sht.Cells(lcnt, 2) = “'" & bf.GetDataUTF16(DescriptorValueLength – 2)
- bf.SkipData (2)
- Case “WM/Picture"
- lcnt = lcnt + 1
- sht.Cells(lcnt, 1) = Mid(DescriptorName, 4)
- bf.SkipData (7)
- JpegLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(4)))
- sht.Cells(lcnt, 3) = “'" & Right(“0000000" & Hex(JpegLength), 8)
- sht.Cells(lcnt, 2) = bf.GetDataUTF16(20)
- bf.SkipData (4)
- bf.SkipData (JpegLength)
- Case Else
- bf.SkipData (4)
- DescriptorValueLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- bf.SkipData (DescriptorValueLength)
- End Select
- Next i
- Case Else
- bf.SkipData (CLng(“&H" & wLen) – 24)
- End Select
- Loop
- Set bf = Nothing
- End Sub
■WMAファイルのタグ情報から画像データを抽出する処理
WMAファイルのタグ情報を読み込み、画像データをファイルに出力するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。
処理の概要
処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、WMAファイルを読み込み
②WMAファイルのタグ情報を解析し、画像データを取得してファイルに出力
③使用済のオブジェクトを破棄
サンプル・プログラム
行番号15でBinary Fileオブジェクトをインスタンス化し、行番号16でM4Aファイルを読み込んでいます。
行番号18~50の繰返し処理のうち、行番号26はHeader Object、行番号29~46はExtended Content Encryption Object、行番号48はそれ以外のObjectの処理です(Content Description Objectは使用したいため、行番号48で読み飛ばしています)。
行番号36~39の「添付画像」に関する処理の中で、画像データをJPEGファイルに出力しています。
- Dim sht, bf As Object
- Dim wLoc, wLen, wGUID, DescriptorName As String
- Dim EntNum, i As Long
- Dim TitleLength As Long
- Dim AuthorLength As Long
- Dim CopyrightLength As Long
- Dim DescriptionLength As Long
- Dim DescriptorValueLength As Long
- Dim RatingLength As Long
- Dim DescriptorNameLength As Long
- Dim JpegLength As Long
- Private Sub Sample2()
- Set sht = ActiveSheet
- Set bf = New BinaryFile
- bf.InputFile (“C:\work\xxx.wma")
- Do While bf.CurrentPosition < bf.FileSize
- wLoc = bf.GetPositionHex
- wGUID = bf.ConvertEndian(bf.GetDataHex(4)) & “-" & bf.ConvertEndian(bf.GetDataHex(2)) & “-" & bf.ConvertEndian(bf.GetDataHex(2)) & “-" & bf.GetDataHex(2) & “-" & bf.GetDataHex(6)
- wLen = bf.ConvertEndian(bf.GetDataHex(4))
- bf.SkipData (4)
- Select Case wGUID
- 'Header Object
- Case “75B22630-668E-11CF-A6D9-00AA0062CE6C"
- bf.SkipData (6)
- 'Extended Content Encryption Object
- Case “D2D0A440-E307-11D2-97F0-00A0C95EA850"
- EntNum = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- For i = 1 To EntNum
- DescriptorNameLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- DescriptorName = bf.GetDataUTF16(DescriptorNameLength – 2)
- Select Case DescriptorName
- Case “WM/Picture"
- bf.SkipData (7)
- JpegLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(4)))
- bf.SkipData (24)
- bf.TransferData (JpegLength)
- bf.OutputFile (“C:\work\xxx.jpg")
- Exit Do
- Case Else
- bf.SkipData (4)
- DescriptorValueLength = CLng(“&H" & bf.ConvertEndian(bf.GetDataHex(2)))
- bf.SkipData (DescriptorValueLength)
- End Select
- Next i
- Case Else
- bf.SkipData (CLng(“&H" & wLen) – 24)
- End Select
- Loop
- Set bf = Nothing
- End Sub
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ
ディスカッション
コメント一覧
まだ、コメントがありません