ASF オブジェクト
Heade Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に定義された数だけ、以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 Length と Codec Description Length が文字数という点に留意する必要がある。Codec Name と Codec Description は UTF-16LE 文字列なので「長さ x 2」が読み出すバイト数となる。
Content Description Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| Object ID | GUID | Guid | 16 | D2D0A440-E307-11D2-97F0-00A0C95EA850 |
| Object Size | QWORD | UInt64 | 8 | オブジェクト全体のサイズ |
| Content Descriptors Count | WORD | UInt16 | 2 | メタデータの総数 |
言語・ストリームに依存しない、ファイル全体に対するメタデータ。Content Descriptors Count に定義された数だけ以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 など。データの内容は型によって決まる。型は以下の数値が定義される。
| 値 | 型 | 型 (.NET) | サイズ |
|---|---|---|---|
| 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
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に指定された数だけ、以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| Flags | WORD | UInt16 | 2 | フラグ。0 ~ 6 ビットがストリーム番号、それ以降は予約領域 |
| Average Bitrate | DWORD | UInt32 | 4 | 平均ビットレート |
ストリーム内の平均ビットレートを表している。VBR なストリームを扱う場合に使用するのだろうか?
Header Extension Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に示されたサイズ分の領域を持つ。そのため、読み取り処理は以下のような実装になる。
- 「Header Extension Data Size + ストリームの現在位置」を領域の終端位置として記録
- 終了条件を「終端位置 > ストリームの現在位置」とした do-while 内へ以降の処理を実装
- ストリームの現在位置をオブジェクトの始点として記録
- GUID (16 バイト) とオブジェクトのサイズ (8 バイト) を記録
- オブジェクトを読む
- ストリームを先頭から「オブジェクトの始点 + オブジェクトのサイズ」の位置へシークする
Language List Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に定義された数だけ以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 の拡張タグエディタを利用して日本語と英語 (米国) のメタデータを設定したところ、このリストには以下のようなデータが格納されていた。
- ja
- ja-JP
- en-US
日本語として ja と ja-JP が定義されている上、ja-JP は前述の Language Strings (Windows) には掲載されていない。このような場合、メタデータを操作する側としては、どのように言語を扱うのか判断が難しいところである。
Metadata Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に定義された数だけ以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 番なのか不明である。
Metadata Library Object
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に定義された数だけ以下のデータが続く。
| 名前 | 型 | 型 (.NET) | サイズ | 内容 |
|---|---|---|---|---|
| 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 に対応する言語インデックスが追加されている。