オブジェクト

2011年3月14日 0

ASF のメタデータに関するオブジェクトをまとめる。

もくじ

Heade Object

名前 サイズ 内容
Object ID GUID Guid 16 75B22630-668E-11CF-A6D9-00AA0062CE6C
Object Size QWORD UInt64 8 Header Object 全体のサイズ
Number of Header Objects DWORD UInt32 4 Header Object に含まれる、子オブジェクトの総数。
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 86D15240-311D-11D0-A3A4-00A0C90348F6
Object Size QWORD UInt64 8 オブジェクト全体のサイズ
Codec Entries Count DWORD UInt32 4 コーデック情報の総数

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

名前 サイズ 内容
Type WORD UInt16 2 0x0001 = 動画、0x0002 = オーディオ、0xFFFF = 未知のコーデック
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 75B22633-668E-11CF-A6D9-00AA0062CE6C
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 D2D0A440-E307-11D2-97F0-00A0C95EA850
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 4
0x00003 DWORD UInt32 4
0x00004 QWORD UInt64 8
0x00005 WORD UInt16 2

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

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

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

File Properties Object

名前 サイズ 内容
Object ID GUID Guid 16 8CABDCA1-A947-11CF-8EE4-00C00C205365
Object Size QWORD UInt64 8 オブジェクト全体のサイズ
File ID GUID Guid 16 ファイル ID
File Size QWORD UInt64 8 ファイルのサイズ
Creation Date QWORD UInt64 8 ファイルの作成日 ( UTC )
Data Packets Count QWORD UInt64 8 Data Object 内に存在するパケットエントリの総数
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 8CABDCA1-A947-11CF-8EE4-00C00C205365
Object Size QWORD UInt64 8 オブジェクト全体のサイズ
Bitrate Records Count WORD UInt16 2 Bitrate Records の総数。

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

名前 サイズ 内容
Flags WORD UInt16 2 フラグ。0 ~ 6 ビットがストリーム番号、それ以降は予約領域
Average Bitrate DWORD UInt32 4 平均ビットレート

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

Header Extension Object

名前 サイズ 内容
Object ID GUID Guid 16 5FBF03B5-A92E-11CF-8EE3-00C00C205365
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. ストリームを先頭から「オブジェクトの始点 + オブジェクトのサイズ」の位置へシークする

Header Extension Object : Language List Object

名前 サイズ 内容
Object ID GUID Guid 16 7C4346A9-EFE0-4BFC-B229-393EDE415C85
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 言語 ID のバイト数
Language ID WCHAR char * 言語 ID

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) には掲載されていない。このような場合、メタデータを操作する側としては、どのように言語を扱うのか判断が難しいところである。

Header Extension Object : Metadata Object

名前 サイズ 内容
Object ID GUID Guid 16 C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA
Object Size QWORD UInt64 8 オブジェクト全体のサイズ
Description Records Count WORD UInt16 2 メタデータの総数

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

名前 サイズ 内容
Reserved WORD UInt16 2 予約領域 ( 値は常に 0 となる )
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 番なのか不明である。

Header Extension Object : Metadata Library Object

名前 サイズ 内容
Object ID GUID Guid 16 44231C94-9498-49D1-A141-1D134E457054
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 に対応する言語インデックスが追加されている。