Excel VBAでファイル解析(M4Aファイル、MP4ファイル編)

2024-01-05

■M4AファイルとMP4ファイルの概要

M4Aファイルは音声データを記録するファイル形式の一つで、MPEG-4規格で定められたMP4ファイル形式を音声用にApple社が独自に拡張したもの。AAC形式またはApple Lossless(ALAC)形式で圧縮した音声データを収録できます。

MP4はMPEG-4規格の一部として策定された、動画や音声などを記録するためのファイル形式(コンテナ・フォーマット)の一つで、Apple社がQuickTime技術の一部として開発したMOVファイル形式を基に策定されたものです。

結果的にM4AファイルはMP4ファイルの仕様を拡張した形になっていますので、先にMP4ファイルの仕様を説明した後、M4Aファイル固有の仕様を説明します。

なお、それぞれの規格で定められている内容は多岐に亘りますので、本稿ではタグ情報(「アルバム名」「年」「トラック番号」「アーティスト名」「曲名」「添付画像」)を取出すことに目的を絞って説明します。

MP4ファイルの仕様

MP4ファイルはBOXの集合体となっており、さまざまなBOXが定義されています。
BOXの基本構造は以下の通りシンプルな形ですが、BOXの種類毎に「data」の内容が異なるうえ、BOXがネストした形で構成されている(「data」部分に別のBOXが含まれている)ため、ファイルの中身を解析するためにはBOXの種類や構造を意識する必要があります。

(BOXの基本構造)

オフセット 長さ 説明
0 4 size
4 4 type
8 可変長 data

MP4の規格で定められているBOXの種類は、下表の通りです。
⇒詳細はMPEGのサイト(mpeg.chiariglione.org)で開示されている、以下の規格書を参照して下さい。

  • ISO/IEC 14496-12 5th edition
  • Information technology-Coding of audio-visual objects-
  • Part 12:ISO base media file format

(BOXの種類)

Box types Spec
ftyp 4.3 file type and compatibility
pdin 8.1.3 progressive download information
moov 8.2.1 container for all the metadata
mvhd 8.2.2 movie header, overall declarations
trak 8.3.1 container for an individual track or stream
tkhd 8.3.2 track header, overall information about the track
tref 8.3.3 track reference container
trgr 8.3.4 track grouping indication
edts 8.6.4 edit list container
elst 8.6.6 an edit list
mdia 8.4 container for the media information in a track
mdhd 8.4.2 media header, overall information about the media
hdlr 8.4.3 handler, declares the media (handler) type
minf 8.4.4 media information container
vmhd 8.4.5.2 video media header, overall information (video track only)
smhd 8.4.5.3 sound media header, overall information (sound track only)
hmhd 8.4.5.4 hint media header, overall information (hint track only)
nmhd 8.4.5.5 Null media header, overall information (some tracks only)
dinf 8.5 data information box, container
dref 8.7.2 data reference box, declares source(s) of media data in track
stbl 8.5 sample table box, container for the time/space map
stsd 8.5.2 sample descriptions (codec types, initialization etc.)
avc1 ISO/IEC 14496-15 AVC file format
avcC ISO/IEC 14496-15 AVC file format
stts 8.6.1.2 (decoding) time-to-sample
ctts 8.6.1.3 (composition) time to sample
cslg 8.6.1.4 composition to decode timeline mapping
stsc 8.7.4 sample-to-chunk, partial data-offset information
stsz 8.7.3.2 sample sizes (framing)
stz2 8.7.3.3 compact sample sizes (framing)
stco 8.7.5 chunk offset, partial data-offset information
co64 8.7.5 64-bit chunk offset
stss 8.6.2 sync sample table
stsh 8.6.3 shadow sync sample table
padb 8.7.6 sample padding bits
stdp 8.7.6 sample degradation priority
sdtp 8.6.4 independent and disposable samples
sbgp 8.9.2 sample-to-group
sgpd 8.9.3 sample group description
subs 8.7.7 sub-sample information
saiz 8.7.8 sample auxiliary information sizes
saio 8.7.9 sample auxiliary information offsets
udta 8.10.1 user-data
meta QuickTime File Format Specification
hdlr QuickTime File Format Specification
ilst QuickTime File Format Specification
mvex 8.8.1 movie extends box
mehd 8.8.2 movie extends header box
trex 8.8.3 track extends defaults
leva 8.8.13 level assignment
moof 8.8.4 movie fragment
mfhd 8.8.5 movie fragment header
traf 8.8.6 track fragment
tfhd 8.8.7 track fragment header
trun 8.8.8 track fragment run
sbgp 8.9.2 sample-to-group
sgpd 8.9.3 sample group description
subs 8.7.7 sub-sample information
saiz 8.7.8 sample auxiliary information sizes
saio 8.7.9 sample auxiliary information offsets
tfdt 8.8.12 track fragment decode time
mfra 8.8.9 movie fragment random access
tfra 8.8.10 track fragment random access
mfro 8.8.11 movie fragment random access offset
mdat 8.2.2 media data container
free 8.1.2 free space
skip 8.1.2 free space
udta 8.10.1 user-data
cprt 8.10.2 copyright etc.
tsel 8.10.3 track selection box
strk 8.14.3 sub track box
stri 8.14.4 sub track information box
strd 8.14.5 sub track definition box
meta 8.11.1 metadata
hdlr 8.4.3 handler, declares the metadata (handler) type
dinf 8.5 data information box, container
dref 8.7.2 data reference box, declares source(s) of metadata items
iloc 8.11.3 item location
ipro 8.11.5 item protection
sinf 8.12.1 protection scheme information box
frma 8.12.2 original format box
schm 8.12.5 scheme type box
schi 8.12.6 scheme information box
iinf 8.11.6 item information
xml 8.11.2 XML container
bxml 8.11.2 binary XML container
pitm 8.11.4 primary item reference
fiin 8.13.2 file delivery item information
paen 8.13.2 partition entry
fire 8.13.7 file reservoir
fpar 8.13.3 file partition
fecr 8.13.4 FEC reservoir
segr 8.13.5 file delivery session group
gitn 8.13.6 group id to name
idat 8.11.11 item data
iref 8.11.12 item reference
meco 8.11.7 additional metadata container
mere 8.11.8 metabox relation
styp 8.16.2 segment type
sidx 8.16.3 segment index
ssix 8.16.4 subsegment index
prft 8.16.5 producer reference time

M4Aファイルの仕様

MP4ファイルのBOX一覧(前掲の表)の中に「QuickTime File Format Specification」と書かれているBOXがありますが、その中の1つである『ilst』の中にタグ情報を保有しています。
タグ情報はMP4ファイルのBOXと同様の形式で格納されており、主な項目は下表の通りです。
⇒詳細はAppleのサイト(QuickTime File Format Specification)を参照して下さい。
(QuickTime File Formatでは、BOXのことをAtomと呼んでいるので注意して下さい)

(User data list entry types)

List entry type 説明
'©alb’ アルバム名
'©day’
'trkn’ トラック番号
'©ART’ アーティスト名
'©nam’ 曲名
'covr’ 添付画像

(注)List entry typeの中の『©(著作権マーク)』の文字コードは『&HA9』となっており、ISO 8859-1では『©(著作権マーク)』ですが、JIS X 0201では『ゥ(カナ小文字のゥ)』になります。

■M4Aファイル(またはMP4ファイル)のBOXをExcelシートに一覧表示する処理

M4Aファイル(またはMP4ファイル)を読み込み、BOXの一覧をExcelシートに表示するプログラムです。
BOXの階層構造を把握しやすくするため、階層が深くなる毎にBox typeを右にずらして表示しています(下図参照)。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。

(実行結果イメージ)

処理の概要

処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、M4Aファイル(またはMP4ファイル)を読み込み
②M4Aファイル(またはMP4ファイル)を先頭から順に解析し、必要な情報を取得してExcelシートにセット
③使用済のオブジェクトを破棄

サンプル・プログラム

行番号7でBinary Fileオブジェクトをインスタンス化し、行番号8でM4Aファイルを読み込んだ後、階層に応じてBOX-IDをずらして表示するため、BOXの取得処理をサブルーチン化し、再帰的に呼び出しています。
サブルーチンの中は、行番号19でlevel(次元数)のカウント・アップ、行番号20~51で繰返し処理、行番号52でlevel(次元数)のカウント・ダウンを行っています。
行番号25~29が「ilst」の中のデータ(タグ情報)を読み出す処理、行番号33~40がBOXがネストしているケースの処理、行番号42~46が最下層のBOXに関する処理です。

  1. Dim sht, bf As Object
  2. Dim rcnt, level As Long
  3. Private Sub Sample1()
  4.     Set sht = ActiveSheet
  5.     sht.Cells.NumberFormatLocal = “@"
  6.     Set bf = New BinaryFile
  7.     bf.InputFile (“C:\work\xxx.m4a")
  8.     rcnt = 0
  9.     level = 0
  10.     Call 展開_Sub(“root", bf.CurrentPosition, bf.FileSize)
  11. End Sub
  12. Private Sub 展開_Sub(ParentID As String, StartLoc As Long, BoxSize As Long)
  13.     Dim sLoc As Long
  14.     Dim sLen As Long
  15.     Dim sID As String
  16.     level = level + 1
  17.     Do While bf.CurrentPosition < StartLoc + BoxSize – 12
  18.         sLoc = bf.CurrentPosition
  19.         sLen = bf.GetData(4)
  20.         sID = bf.GetDataChar(4)
  21.         If ParentID = “ilst" Then
  22.             rcnt = rcnt + 1
  23.             sht.Cells(rcnt, 1) = Right(“0000000" & Hex(sLoc), 8)
  24.             sht.Cells(rcnt, 2) = Right(“0000000" & Hex(sLen), 8)
  25.             sht.Cells(rcnt, level + 2) = sID
  26.             bf.SkipData (sLen – 8)
  27.         Else
  28.             Select Case sID
  29.             Case “moov", “trak", “edts", “mdia", “minf", “dinf", “stbl", “stsd", “avc1", “udta", “hdlr", “ilst", “mvex", “moof", “traf", “mfra", “skip", “cprt", “strk", “meta", “ipro", “sinf", “flin", “paen", “meco"
  30.                 rcnt = rcnt + 1
  31.                 sht.Cells(rcnt, 1) = Right(“0000000" & Hex(sLoc), 8)
  32.                 sht.Cells(rcnt, 2) = Right(“0000000" & Hex(sLen), 8)
  33.                 sht.Cells(rcnt, level + 2) = sID
  34.                 If sID = “meta" Then
  35.                     bf.SkipData (4)
  36.                 End If
  37.                 Call 展開_Sub(sID, bf.CurrentPosition, sLen)
  38.             Case “ftyp", “pdin", “mvhd", “tkhd", “trgr", “elst", “mdhd", “hdlr", “vmhd", “smhd", “hmhd", “nmhd", “dref", “avcC", “stts", “ctts""cslg", “stsc", “stsz", “stz2", “stco", “co64", “stss", “stsh", “padb", “stdp", “sdtp", “sbgp", “sgpd", “subs", “saiz", “saio", “mehd", “trex", “leva", “mfhd", “tfhd", “trun", “sbgp", “sgpd", “subs", “tfdt", “tfra", “mfro", “mdat", “free", “tsel", “stri", “strd", “iloc", “frma", “schm", “schi", “iinf", “xml “, “bxml", “pitm", “fire", “fpar", “fecr", “segr", “gitn", “idat", “iref", “mere", “styp", “sidx", “ssix", “prft"
  39.                 rcnt = rcnt + 1
  40.                 sht.Cells(rcnt, 1) = Right(“0000000" & Hex(sLoc), 8)
  41.                 sht.Cells(rcnt, 2) = Right(“0000000" & Hex(sLen), 8)
  42.                 sht.Cells(rcnt, level + 2) = sID
  43.                 bf.SkipData (sLen – 8)
  44.             Case Else
  45.                 bf.CurrentPosition = StartLoc + BoxSize – 8
  46.             End Select
  47.         End If
  48.     Loop
  49.     level = level – 1
  50. End Sub

■M4Aファイルのタグ情報をExcelシートに表示する処理

M4Aファイルのタグ情報を読み込み、Excelシートに表示するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。

処理の概要

処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、M4Aファイルを読み込み
②M4Aファイルのタグ情報を解析し、必要な情報を取得してExcelシートにセット
③使用済のオブジェクトを破棄

サンプル・プログラム

行番号10でBinary Fileオブジェクトをインスタンス化し、行番号11でM4Aファイルを読み込んでいます。
行番号14~53の繰返し処理の中では、タグ情報に辿り着くために必要なBOXを「moov」「trak」「meta」「udta」「ilst」の順に辿っています。
行番号25~29は「アルバム名」「アーティスト名」「曲名」、行番号31~35は「年」、行番号37~42は「トラック番号」、行番号44~49は「添付画像」に関する処理です。

(注)「アルバム名」「アーティスト名」「曲名」はUTF-16またはUTF-8で格納されています。
以下のプログラムはUTF-16で格納されているものとして処理を記述していますが、UTF-8で格納されている場合は行番号29のGetDataUTF16メソッドをGetDataUTF8メソッドに置換えて下さい。

  1. Dim sht, bf As Object
  2. Dim wLoc As Long
  3. Dim wLen As Long
  4. Dim wID As String
  5. Dim rcnt As Long
  6. Private Sub Sample2()
  7.     Set sht = ActiveSheet
  8.     sht.Cells.NumberFormatLocal = “@"
  9.     Set bf = New BinaryFile
  10.     bf.InputFile (“C:\work\xxx.m4a")
  11.     rcnt = 0
  12.     Do While bf.CurrentPosition < bf.FileSize
  13.         wLoc = bf.CurrentPosition
  14.         wLen = bf.GetData(4)
  15.         Do While wLen = 0
  16.             wLoc = bf.CurrentPosition
  17.             wLen = bf.GetData(4)
  18.         Loop
  19.         wID = bf.GetDataChar(4)
  20.         Select Case wID
  21.         Case “moov", “trak", “meta", “udta", “ilst"
  22.         Case “ゥalb", “ゥART", “ゥnam"
  23.             wLen = bf.GetData(4)
  24.             bf.SkipData (12)
  25.             rcnt = rcnt + 1
  26.             sht.Cells(rcnt, 1) = wID
  27.             sht.Cells(rcnt, 2) = bf.GetDataUTF16(wLen – 16)
  28.         Case “ゥday"
  29.             wLen = bf.GetData(4)
  30.             bf.SkipData (12)
  31.             rcnt = rcnt + 1
  32.             sht.Cells(rcnt, 1) = wID
  33.             sht.Cells(rcnt, 2) = bf.GetDataChar(wLen – 16)
  34.         Case “trkn"
  35.             wLen = bf.GetData(4)
  36.             bf.SkipData (14)
  37.             rcnt = rcnt + 1
  38.             sht.Cells(rcnt, 1) = wID
  39.             sht.Cells(rcnt, 2) = bf.GetData(2)
  40.             bf.SkipData (wLen – 20)
  41.         Case “covr"
  42.             wLen = bf.GetData(4)
  43.             bf.SkipData (4)
  44.             rcnt = rcnt + 1
  45.             sht.Cells(rcnt, 1) = wID
  46.             sht.Cells(rcnt, 2) = “あり"
  47.             bf.SkipData (wLen – 8)
  48.         Case Else
  49.             bf.SkipData (wLen – 8)
  50.         End Select
  51.     Loop
  52.     Set bf = Nothing
  53. End Sub

■M4Aファイルのタグ情報から画像データを抽出する処理

M4Aファイルのタグ情報を読み込み、画像データをファイルに出力するプログラムです。
⇒サンプル・プログラムで使用している、Binary Fileクラスの詳細については、Excel VBAでファイル解析(事前準備編)を参照して下さい。

処理の概要

処理の流れは以下の通りです。
①Binary Fileオブジェクトをインスタンス化し、M4Aファイルを読み込み
②M4Aファイルのタグ情報を解析し、画像データを取得してファイルに出力
③使用済のオブジェクトを破棄

サンプル・プログラム

行番号8でBinary Fileオブジェクトをインスタンス化し、行番号9でM4Aファイルを読み込んでいます。
行番号12~34の繰返し処理の中では、タグ情報に辿り着くために必要なBOXを「moov」「trak」「meta」「udta」「ilst」の順に辿っています。
行番号23~24で「アルバム名」「年」「トラック番号」「アーティスト名」「曲名」を読み飛ばし、行番号26~29の「添付画像」に関する処理の中で、画像データをJPEGファイルに出力しています。

  1. Dim sht, bf As Object
  2. Dim wLoc As Long
  3. Dim wLen As Long
  4. Dim wID As String
  5. Dim lcnt As Long
  6. Private Sub Sample3()
  7.     Set bf = New BinaryFile
  8.     bf.InputFile (“C:\work\xxx.m4a")
  9.     lcnt = 0
  10.     Do While bf.CurrentPosition < bf.FileSize
  11.         wLoc = bf.CurrentPosition
  12.         wLen = bf.GetData(4)
  13.         Do While wLen = 0
  14.             wLoc = bf.CurrentPosition
  15.             wLen = bf.GetData(4)
  16.         Loop
  17.         wID = bf.GetDataChar(4)
  18.         Select Case wID
  19.         Case “moov", “trak", “meta", “udta", “ilst"
  20.         Case “ゥalb", “ゥART", “ゥnam", “ゥday", “trkn"
  21.             wLen = bf.GetData(4)
  22.             bf.SkipData (wLen – 4)
  23.         Case “covr"
  24.             wLen = bf.GetData(4)
  25.             bf.SkipData (12)
  26.             bf.TransferData (wLen)
  27.             bf.OutputFile (“C:\work\xxx.jpg")
  28.             Exit Do
  29.         Case Else
  30.             bf.SkipData (wLen – 8)
  31.         End Select
  32.     Loop
  33.     Set bf = Nothing
  34. End Sub

 

国本温子(著),緑川吉行(著),できるシリーズ編集部(著)
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ

大村あつし(著),古川順平(著)
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ

高橋宣成(著)
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ

ファイル解析

Posted by hides