ASF
July 12, 2010
ASF ファイルのデータ構造についてのまとめ。メタデータを操作するうえで重要そうな部分を書き出してみる。Windows Media Format SDK ないしは Runtime に関して言及する場合は正式名称が長いので WMF と記述する。
参考資料
参考資料は以下。
- Microsoft Windows Media - Advanced Systems Format (ASF) Specification
- Windows Media Format 11 SDK (Windows)
ASF ファイルの基本構造
ASF ファイルは、オブジェクトと呼ばれるチャンク構造を持つデータが連なって構成されている。ひとつのオブジェクトを表で表すと以下のようになる。
名前 | サイズ (byte) | 内容 |
---|---|---|
Object GUID | 16 | オブジェクトの種別を示す GUID。 |
Object Size | 8 | オブジェクト全体のサイズ。大きさは「GUID (16 byte) + サイズ (8 byte) + データ部分の長さ」となる。 |
Object Data | 可変長 | オブジェクトのデータ。中に子オブジェクトを持つ場合もある。 |
ファイルのトップレベルに置かれるオブジェクトは Header Object や Data Object など。メタデータは Header Object、音声や動画は Data Object に格納される。以降は Header Object と、その子となるオブジェクトについて調べてゆく。
各オブジェクトの内容表記は以下のように書く。
- 型は ASF ファイル仕様書と .NET Framework のものを併記
- ファイル操作はバイト単位でおこなうことが多いため、サイズ欄はバイト数で表記
文字列の扱いについて
ASF のメタデータにおける文字列は基本的に UTF-16LE となる (一部、ASCII もある)。サロゲート ペアについても考慮しておいたほうがよいかも。
文字列はおおむね NULL 終端となる。C# の String
は NULL 終端ではないため Encoding.Unicode.GetString()
で得られたものをそのまま利用してはいけない。終端が NULL 文字 \0
ならば事前に除去する必要あり。逆に書き込みをおこなう場合は、NULL 文字を足した後にバイト配列化すること。
特別なデータ
ASF の基本的なデータ型に該当しないものはバイナリ扱いとなりタグの種別ごとに異なる解釈が必要となる。以下にそれらをまとめてゆく。
画像
WM/Picture として定義される画像データの内容は WM_PICTURE 構造体として表される。構造体のメンバやリファレンスを読むと分かりやすいのだが、これは ID3v2.3 以降の APIC との相互運用を考慮して定義されている。
typedef struct _WMPicture {
LPWSTR pwszMIMEType;
BYTE bPictureType;
LPWSTR pwszDescription;
DWORD dwDataLen;
BYTE * pbData;
} WM_PICTURE;
Windows Media Player 11 で画像を埋め込み、バイナリ エディタで WM/Picture
の部分を調べた結果、データ構造は WM_PICTURE
と異なり、以下のようになっていた。
名前 | 型 | サイズ | 値 |
---|---|---|---|
bPictureType | BYTE | byte | 1 |
dwDataLen | DWORD | UInt32 | 4 |
pwszMIMEType | WCHAR | char | * |
pwszDescription | WCHAR | char | * |
pbData | BYTE | byte | * |
はじめに固定長である、画像の種類と画像データのバイト数が並び、その後に可変長の MIME、説明、画像データが続く。
MIME と説明の長さは指定されていないが NULL 終端されているため、それを目印に読み込む。文字コードが UTF-16LE なので終端は 00 00
となるが、その直前がアルファベットなど 2 バイト目が 00
になる文字の場合もあるから終端の検出処理には注意が必要。