アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

ASF オブジェクト

March 14, 2011ASF

Heade Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Number of Header Objects DWORD UInt32 4
Reserved1 BYTE byte 1
Reserved2 BYTE byte 1

ASF ファイルは Header Object から始まる。ファイル操作をおこなう場合は、まず先頭から 16 バイト読み込み、それが Header Object の GUID であることを確認する。Header Object の後には、Number of Header Objects として格納された数の子オブジェクトが続いてゆく。

Codec List Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Codec Entries Count DWORD UInt32 4

コーデック情報リスト。Codec Entries には Codec Entries Count に定義された数だけ、以下のデータが続く。

名前 サイズ 内容
Type WORD UInt16 2
Object Size QWORD UInt64 8
Codec Name Length WORD UInt16 2
Codec Name WCHAR char *
Codec Description Length WORD UInt16 2
Codec Description WCHAR char *
Codec Information Length WORD UInt16 2
Codec Information BYTE byte *

他のテキスト系メタデータと異なり、Codec Name LengthCodec Description Length が文字数という点に留意する必要がある。Codec NameCodec Description は UTF-16LE 文字列なので「長さ x 2」が読み出すバイト数となる。

Content Description Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Title Length WORD UInt16 2
Author Length WORD UInt16 2
Copyright Length WORD UInt16 2
Description Length WORD UInt16 2
Rating Length WORD UInt16 2
Title WCHAR char *
Author WCHAR char *
Copyright WCHAR char *
Description WCHAR char *
Rating WCHAR char *

コンテンツの基本的なメタデータが格納されている。これらは言語非依存で、常にデータ領域が確保されるようだ。Windows Media Player 11 の拡張タグエディタで、コメントを言語別にいくつか書いてみたところ、このオブジェクトの Description Length は 0、Description は空となり、代りに Metadata Library Object へ言語別に登録されていた。

多言語・多ストリームにきちんと対応しているメタデータエディタは少なく、Windows Media Player ですら一部のタグしか対応できていない。一方、ASF や WMA に対応しているアプリケーションなら、大概はこのオブジェクトに書かれるデータに対応していると思われる。

よって、多言語・多ストリーム対応する際は、Metadata Library Object と同時にこちらにもデータを設定したほうがよいだろう。

Extended Content Description Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Content Descriptors Count WORD UInt16 2

言語・ストリームに依存しない、ファイル全体に対するメタデータ。Content Descriptors Count に定義された数だけ以下のデータが続く。

名前 サイズ 内容
Descriptor Name Length WORD UInt16 2
Descriptor Name WCHAR char *
Descriptor Value Data Type WORD UInt16 2
Descriptor Value Length WORD UInt16 2
Descriptor Value BYTE byte[] *

メタデータは名前、型、データで構成されている。名前には WMF でおなじみの文字列がはいる。例えば WM/AlbumArtist など。データの内容は型によって決まる。型は以下の数値が定義される。

サイズ
0x00000 WCHAR char
0x00001 BYTE byte[]
0x00002 BOOL bool
0x00003 DWORD UInt32
0x00004 QWORD UInt64
0x00005 WORD UInt16

C# の型に変換する場合、WCHAR は Encoding.Unicode.GetString() を使用し、得られた文字列の末尾に NULL 文字があれば削除する。C# の文字列は NULL 文字終端ではないので、これを行わないと正しく処理できない。書き込むときは NULL 文字を足した上でバイト配列にする。

BOOL、DWORD、QWORD、WORD は、BitConverter.To~() でそのまま変換できる。

BYTE の場合は専用のデータ型となるので、データ名を判定して自前で変換する必要がある。ジャケット画像やタイムライン付きの歌詞データなどがこれに該当する。

File Properties Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
File ID GUID Guid 16
File Size QWORD UInt64 8
Creation Date QWORD UInt64 8
Data Packets Count QWORD UInt64 8
Play Duration QWORD UInt64 8
Send Duration QWORD UInt64 8
Preroll QWORD UInt64 8
Flags DWORD UInt32 4
Minimum Data Packet Size DWORD UInt32 4
Maximum Data Packet Size DWORD UInt32 4
Maximum Bitrate DWORD UInt32 4

ファイル情報が格納されている。File ID は Data Object 側の定義と対応している必要があり、ファイルを編集した場合は、ユニークな値を再割り当てする必要があるとのこと。編集とは Data Object 側のことを指しており、メタデータの場合は更新不要と思われる。

File Size はファイルを編集した場合、必ず更新しなければならない。このデータは WMF の FileSize タグに対応する。

Creation Date はファイル作成日なので、ゼロからファイルを構築するときだけ設定するのだろう。

コンテンツの再生時間を取得する場合は、Play Duration から Preroll を差し引く必要がある。Preroll はミリ秒単位で格納されており、10,000 倍することで Play Duration と同位になる。つまり時間は「Play Duration - (Preroll x 10,000)」で求められる。この数値は WMF の Duration タグに対応する。

他のデーターは、オンラインストリーミングに関するものと予想されるので割愛。

Stream Bitrate Properties Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Bitrate Records Count WORD UInt16 2

ビットレートに関する情報を格納している。Bitrate Records Count に指定された数だけ、以下のデータが続く。

名前 サイズ 内容
Flags WORD UInt16 2
Average Bitrate DWORD UInt32 4

ストリーム内の平均ビットレートを表している。VBR なストリームを扱う場合に使用するのだろうか?

Header Extension Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Reserved Field 1 GUID Guid 16
Reserved Field 2 WORD UInt16 2
Header Extension Data Size DWORD UInt32 4

拡張ヘッダ情報が格納されている。通常のヘッダ情報は Header Object、オプション情報はこのオブジェクトの子となる。階層構造で表すと「Header Object → Header Extension Object → Language List Object、Metadata Object、...etc」のように構成される。

オプション情報は他のオブジェクトと同様に、識別子となる GUID とオブジェクトサイズを持ち、Header Extension Data Size に示されたサイズ分の領域を持つ。そのため、読み取り処理は以下のような実装になる。

  1. 「Header Extension Data Size + ストリームの現在位置」を領域の終端位置として記録
  2. 終了条件を「終端位置 > ストリームの現在位置」とした do-while 内へ以降の処理を実装
  3. ストリームの現在位置をオブジェクトの始点として記録
  4. GUID (16 バイト) とオブジェクトのサイズ (8 バイト) を記録
  5. オブジェクトを読む
  6. ストリームを先頭から「オブジェクトの始点 + オブジェクトのサイズ」の位置へシークする

Language List Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Language ID Records Count WORD UInt16 2

Header Extension Object 内のオブジェクト。言語リストを格納している。このオブジェクトは言語依存のメタデータを持つ場合に必要となる。Language ID Records Count に定義された数だけ以下のデータが続く。

名前 サイズ 内容
Language ID Length BYTE byte 1
Language ID WCHAR char *

Language ID は UTF-16LE の NULL 終端文字列で、RFC-1766 として定義される形式の言語名が格納される。具体的な文字列としては以下を参照のこと。

ただし Windows Vista 日本語の環境で Windows Media Player 11 の拡張タグエディタを利用して日本語と英語 (米国) のメタデータを設定したところ、このリストには以下のようなデータが格納されていた。

  1. ja
  2. ja-JP
  3. en-US

日本語として ja と ja-JP が定義されている上、ja-JP は前述の Language Strings (Windows) には掲載されていない。このような場合、メタデータを操作する側としては、どのように言語を扱うのか判断が難しいところである。

Metadata Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Description Records Count WORD UInt16 2

Header Extension Object 内のオブジェクト。特定のストリームに属し、言語に依存しないメタデータのリストを格納している。Description Records Count に定義された数だけ以下のデータが続く。

名前 サイズ 内容
Reserved WORD UInt16 2
Stream Number WORD UInt16 2
Name Length WORD UInt16 2
Data Type WORD UInt16 2
Data Length DWORD UInt32 4
Name WCHAR char 2
Data BYTE byte[] *

データの配置がすこし異なるが、基本的な内容は Extended Content Description Object と同様。複数のストリームを持つ ASF ファイルの場合、このオブジェクトを利用することで、ストリームごとにメタデータを定義できる。

手持ちの WMA ファイルをダンプしたところ、ストリーム番号 1 に対して「IsVBR」と「 DeviceConformanceTemplate」が定義されていた。ストリーム番号は 0 から開始され、単純なオーディオならばストリーム数は単一だと思っていたので、なぜ 1 番なのか不明である。

Metadata Library Object

名前 サイズ 内容
Object ID GUID Guid 16
Object Size QWORD UInt64 8
Description Records Count WORD UInt16 2

Header Extension Object 内のオブジェクト。特定のストリームに属し、言語に依存するメタデータのリストを格納している。Description Records Count に定義された数だけ以下のデータが続く。

名前 サイズ 内容
Language List Index WORD UInt16 2
Stream Number WORD UInt16 2
Name Length WORD UInt16 2
Data Type WORD UInt16 2
Data Length DWORD UInt32 4
Name WCHAR char 2
Data BYTE byte[] *

データの配置がすこし異なるが、基本的な内容は Extended Content Description Object と同様。Metadata Object を拡張し、Language List Object に対応する言語インデックスが追加されている。