ASF オブジェクト
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 Length と Codec Description Length が文字数という点に留意する必要がある。Codec Name と Codec 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 に示されたサイズ分の領域を持つ。そのため、読み取り処理は以下のような実装になる。
- 「Header Extension Data Size + ストリームの現在位置」を領域の終端位置として記録
- 終了条件を「終端位置 > ストリームの現在位置」とした do-while 内へ以降の処理を実装
- ストリームの現在位置をオブジェクトの始点として記録
- GUID (16 バイト) とオブジェクトのサイズ (8 バイト) を記録
- オブジェクトを読む
- ストリームを先頭から「オブジェクトの始点 + オブジェクトのサイズ」の位置へシークする
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 の拡張タグエディタを利用して日本語と英語 (米国) のメタデータを設定したところ、このリストには以下のようなデータが格納されていた。
- ja
- ja-JP
- 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 に対応する言語インデックスが追加されている。