携帯には標準装備と言えるまでになったモバイルテレビ放送であるワンセグ放送規格。 通勤時などに便利に使っている人も多いでしょう。この番組には字幕が付いていることが多く、 揺れる車内などで、映像内のテロップが読めなくても、なんとなく中身がわかったりして重宝する。 また、データ放送もきっちりサポートされており、局が提供するちっちゃなホームページという趣のコンテンツも楽しめる。
この字幕を抜き出して、Namazuとかに食わせれば、 テレビ番組を文字列検索 できるのではないか? というのが事の発端である。
読み解くためには資料が必要だ。
1セグ放送教科書 (インプレス標準教科書シリーズ)(羽鳥 光俊) |
→1セグ放送教科書。 万が一買われる人がいれば、e-honで「錦堂 谷書店」を書店登録して買われると僕が喜びます(ぉ)。 あとはARIB(電波産業会)の規格書、STD B-24, STD B-5, STD TR-14。しかし...これらは拾い読みするには 大変なので、なるべく後回しにすることにする。
ワンセグ放送はMPEG-TSで多重化されているので、TSパーサとPESパーサは、どこかから持ってこなければならない。 188バイトに区切られたTSパケットを選別するにはPIDが必要。しかし、字幕に何のPIDが割り当てられているかは、 放送局によって異なる。それはPMTパケットを解析しなければわからないので、PMTパーサも必要。 ワンセグ放送では、PMTテーブルの項目のうち stream type=0x6 (MPEG-2 Packetized Elementary Stream packets containing private data)になっているものが、ほぼ字幕とみて間違いない*1。 より正確にはTableID=0x52のStream Identifierを見付けて(len=1) ESタグの値が0x87 であるもの。ここまでパースすれば完璧。「教科書p148 図5-23」参照。
*1 ちなみにビデオは0xd(ISO/IEC 13818-6 type D),オーディオは0xf(ISO/IEC 13818-7 Audio with ADTS transport syntax)
TSパケットの中身はこういう階層になっている。資料は「教科書p167」。TS,PESの情報はヘッダを読み飛ばす以外に使わないので説明は割愛*1。
TSヘッダ |
PESヘッダ |
data_group() |
data_group()は「ARIB STD-B24 第ー編 第3部 第9章 字幕・文字スーパーの伝送」。data_group()にはdata_group_idという変数があり、これで管理データdata_management_data()と字幕本体caption_data()を区分けする。data_group_idは6bitあるのだが、管理データは0x00か0x20, 字幕本体は0x1〜0x8か0x21〜0x28と2ペアになって分かれている。運用上、放送する字幕言語が1種類(日本語のみ)の場合は、0x00〜の組で運用し、 2種類の場合は0x20〜の組で管理するらしい。つまり、日本語字幕をダンプするという目的を設定したとき、管理テーブルを解析してISO_639_language_codeをサーチして'jpn'の言語テーブル行をみつけ、そのlanguage_tagをとりだし、 管理テーブルのdata_group_id + language_tag + 1したものが字幕のdata_group_idとなる 。
data_management_data()もcaption_data()も字幕本体であるdata_unit()を複数個含む。その総バイト長を指示するdata_unit_loop_length変数が前置されている。
data_unit_loop_length:24 = data_unit() { unit_separator:8 data_unit_parameter:8 data_unit_size:24 for (i = 0; i < data_unit_size; i++) { data_unit_data_byte:8 } }のバイト数 * N回
このN回の方はへッダには表れないので注意。ただ、ダンプして見た限りは1個以上のdata_unit()が入っていること自体けっこう稀。 データ放送やファームウェアアップデートで使われているデータカルーセルとは異なり、PES独立型字幕データにはフラグメントの概念がないため、188バイトに必ず納めなければならず、連続して挿入する場面が考えられないのかもしれない*2。
data_unit_parameter=0x20が本文、0x30がDRCS。DRCSというのはいわゆる外字図形データ*1。本文は Cプロファイル8単位符号 というEUC-JPに似た形式。0x00〜0x1fは制御符号、0xfcxx〜0xffxxは追加符号と外字呼出に割り当てられている。「教科書p168 図5-34」「ARIB STD-B24 第ー編 第3部 第5章」。ただ、普通のPC UNIXに備えられたフォントでは、ARIBの追加符号部分はほとんど表示できないため...字幕放送で使われる音符マークとかが表示できないんだ...。
*1 アナログ放送の時代から使われてたようだ...歴史は意外に古い
2009年1月6日: ディレクトリ指定(D:\TS)に対応。ソースコードとWin32バイナリも同梱。
@echo off :LOOP dumpeit.exe D:\TS goto LOOP
みたいなバッチを書いて実行しておけば、OneTwoFour.exeが作ったそばからTSファイルを変換していきます。 でも、HDDのランダムアクセスが遅い場合はOneTwoFour.exeが落ちるかも。 少しウェイト入れないといけないかもしれません。Linuxなら各種UNIX由来コマンド群と組み合わせたほうが良いでしょう。
どなたか番組表CGI書いていただけませんか。
錦堂_谷書店の宣伝をして頂き、まことにありがとうございますm(_ノ_)m
PMT type=0x0D : DSM_CC section data,type=0x1B: H.264/AVC stream です.