7 : 09 OGMのSRT日本語字幕

← 7‒08 p↑ もくじ i 7‒10 n →

脳は視覚に対する音の遅れを自動補正/ほか

2003年 3月 3日
記事ID d30303

アニメ空間はどのくらい「遠い」か?

2003年3月2日 ―― ネタふり。脳は音がどのくらいの早さで進んで来るか正確に知っている: これは現実世界での実験である。引用すると「実世界において多くの場合、音は眼に見えるものの動きによって生み出されるが、眼に見えるもの(光)と、耳に聞こえるもの(音)とには時間差が生じている。脳は、音の時間遅れを計算に入れて、聞こえた音と見えた光(映像)を統合していることが明らかになった。この視聴覚間情報統合における距離補完の限界が約40メートル近辺であることを明らかにした」

では、仮想的な音源位置がアニメ(ゲーム)空間内部にある場合どうなるだろう。 動画制作の観点から、経験上、字幕は本当の音タイミングより100msほど早く出したほうがぴったりだと感じられる。 字幕は視覚なので事実上、瞬時に目に届いている。ヘッドフォンを使っていれば、音も本当は同時のはずだ。 なぜ100msずらしたほうがいいかについて「文字言語入力の処理は、音声言語入力の処理より遅いのかな?」などと前からふしぎに思っていたのだが、 産業技術総合研究所の上記実験データ(@現実世界)と照合すると、もしかして「脳はアニメの世界を現実に換算して30~40メートルほど向こう」 に認識しているのかもしれない。つまり脳にとって、アニメや映画のキャラたちは30メートルほど先でしゃべっている?

もしこの憶測の通りだとすると、40メートルが補完限界であるということは、仮想的なオーディオ・ビジュアルは、 脳にとって、あたかも「現実空間で処理可能ないちばん遠い地点から発せられているかのごとく」認識されていることになる。 端的に言うと、脳が統合的に認識できる現実空間の「いちばん遠い点」にアニメ空間の座標が張られている(笑)

「アニメ空間と現実空間の距離」の脳内距離空間への射影は補完限界ぎりぎり? 意外に「遠い」ゲーム・アニメの世界 ―― というネタを考えてみましたが。 いかがでしょう。あなたの脳にとって、巨大ロボの操縦席にいる若者は何メートル先で叫んでますか……? もし「主人公のこころの声のときは字幕がぴったりで同時に感じられるが、遠方で叫んでるシーンの声は字幕が100ms早くないと同時に感じられない」なんて実験結果が出たらおもしろいですね。

「視聴覚統合」に関するほかの興味深い例。静かな環境で、目をとじて、うとうとしているときなど、天井のきしみなどの「ぴしっ」という鋭い響きが聞こえるのと同時に、まぶたのうらに閃光のようなものが見えるときがある。これも「音がインプットされたことが原因で、視覚刺激が(誤って)発生している」わけだが、 そのような時系列に反して実際には「同時」に感じられる。たぶん、変な音が聞こえたからには何かが動いているに違いないという脳内モーションサーチアルゴリズムが起動され、動き検出のために視覚野をスキャンしているときの信号が(たまたま静かに目を閉じているので)ノイズみたく感じられ、 さらに、「音とほぼ同時にこのノイズが出たのだから両者は関係あるに違いない」という音ズレ自動補正機能(再シンクロ)が働くのだろう……。 このことを単純に言い表すと、いきなり変な音がしてびっくりして目から星が出たのである。

以上のことをべつの角度から言い表すと、脳はある程度まで時間軸を操作して「自分のロジックにとってつごうの良い過去」をでっちあげている。 夢のなかと現実で同時に落下物が頭にぶつかるような場合、「絶対時間」では現実側でものがぶつかったから夢のストーリーが発生したはずだが、 脳にとっては、夢のストーリーの進行速度に合わせて現実を遅らせて認識していることになる。 (あるいは脳自身は現実をわざと遅らせたというログをとっているが、その秘密を「あなたには」教えてくれない。) なにせ脳自身がストーリーの作者なのだから、そのへんは自由自在なのだ。いや……本当にそうなのだろうか。本当に「脳があるから夢がある」のだろうか。 あんがい、夢というものが先にあって、それを脳のドライバーが検出しているのかもしれない。 ふたり同時に同じ夢を見たりすることがあるのを思えば、脳よりも夢のほうが絶対的な現実かもしれないという可能性も否定できないのだ。

Media Player Classic がUSFサポートへ

2003年3月2日: Media Player Classic 6.4.3.0 - さまざまな改善があるが、 Matroskaのデフォルト字幕フォーマットUSFへの対応が表明されたことに注目したい。 USFをサポートするプレーヤーは、すでに The Core Media Player (TCMP) があるが、VobSub作者である「字幕のグル」Gabest が動いたのは大きい。 ところで、現在のDirectVobSubから例えばカラオケ字幕を動的に生成するのは大変だろうなぁと予測していたが、 TCMP で USF再生を試したところ、何と既存のDirectVobSubよりかえってずっと軽い。 もちろんユニコードなので日本語のサポートも完璧、しかもSRTと違ってフォントの色、サイズそのほかもろもろ指定できる。 字幕をMUXしたい場合、MKV(MCF)/USFは、少なくとも現在のOGM/SRTよりは、格段にすぐれているが、 「すぐれているけどCPU負荷も高いのではないか」と思っていた。それはそうかもしれないが、思ったほど重くないのかもしれない。 Pentium II とか 100MHz が速いと言われていた時代は、そんな昔ではないのだ。 「USFはクロック・ギガのCPUを必要とするから重くて大変」などというのは未来をみすえたフォーマットを策定するにあたって、 どうでもいいことなのかもしれない。というか、850MHz の古いマシンでもカラオケ字幕が完全にソフト再生できたので、 今の DVobSub よりかえって軽い。もっとも、今のTCMPでは、RTL言語がエディタレイヤーのプレゼンテーションになってしまう。 プレフォーマットしてHTMLでいうBIDI強制上書き風に出さない限り、文字位置がずれてしまう。 それにしても、USFでは日本語とアラビア語がすでにふつうに混在でき、何の設定もしないでちゃんとソフト字幕出力されるのだ。 おまけに双方向アルゴリズムが要らない単純なアラビア語文なら、今でも右から左にきちんと出力される。 Windows そのもののAPIを使ってるだけなのだろうが、すでに初期のモジラよりいいぞと。

この記事のURL


[OGM] SRTの整合性チェック&行末に空白挿入するスクリプト

2003年 3月 4日
記事ID d30304

SRTのフォーマットに問題がないか確認しつつ、 字幕データ行の行末に半角スペースを32個ずつ挿入するPerlスクリプト。 日本語の場合は64個挿入したほうが良い。 改訂版では挿入する空白の個数をコマンドラインから指定できる。 別記事SRT日本語字幕 SJIS/UTF-8を参照。 bakasrt_0.3.zip

背景

OGMに MUX するSRTファイルがフィンランド語のように 0x80-FF を含んでいる場合で、 かつ再生環境が、システムの言語設定=日本語の Windows の場合、 VobSub では表示上の行末文字の脱落が起こる場合がある。 これを回避するには、各行末にダミーの空白を入れれば良い。 ([OGM] 0x80-FFを含む字幕の行末が脱落する

そのごウムラウトがつく文字のような特殊文字(0x80-FFの文字)がたくさん含まれている行だと、 行末に空白を数個入れるくらいではまだ足らず、5個や10個挿入する必要があることが分かった。 面倒なので、大は小をかねると32個入れることにしよう。 これを手動でやっていては面倒なのでPerlスクリプトで書いてみた。 ついでにSRTファイル内の整合性チェック(書式やタイムスタンプの内容におかしな場所はないかなど)も行わせる。

もちろん空白の挿入は、その場しのぎであり、美しくない。

使い方

動作環境
perl がインストールされていること
用法
perl bakaSRT.pl filename
出力ファイル名
filename_baka.srt

ソース

必要に応じて以下のスクリプトを適当に修正すれば良い。 英語とフィンランド語で動作確認している。 (日本語のSRTにも使えるはず。) 日本語の場合は64個挿入したほうが良い。 改訂版では挿入する空白の個数をコマンドラインから指定できる。 別記事SRT日本語字幕 SJIS/UTF-8を参照。 もともと行末に1個以上の半角スペースがある場合でも出力ファイルのその行末の半角スペースはちょうど32個になる。 (例えば、このスクリプトを1回通した結果にもう一度この処理を行っても行末のスペースは64個に増えない。)

$about = 'BakaSRT.pl beta';

if( ! defined($ARGV[0]) ) {
    print("Usage: perl BakaSRT.pl filename\n");
    exit;
}

$filename = $ARGV[0];

open IN, "<$filename" or die("Error: Couldn't open '$filename': $!");
open OUT, ">${filename}_baka.srt" or die("Error: Couldn't open '${filename}_baka.srt': $!");

$phase = 1;
$prevline = 0;
$t = -1;

while(<IN>) {
    chomp;
    if( $phase ==1 ) {
        if( /^(\d+)$/ ) {
            if( $1 == $prevline + 1 ) {
                $prevline++;
                $phase = 2;
            } else {
                die("\n\nError: Bad line number around Data $prevline at $filename\n");
            }
        } else {
            print("\n Warning: Bad format around Data $prevline at $filename\n");
        }
    } elsif( $phase == 2 ) {
        if( /^(\d\d)\:(\d\d)\:(\d\d)\,(\d\d\d) \-\-> (\d\d)\:(\d\d)\:(\d\d)\,(\d\d\d)$/ ) {
            $in_time = $1 * 3600 + $2 * 60 + $3 + $4/1000.0;
            $out_time = $5 * 3600 + $6 * 60 + $7 + $8/1000.0;

            if( $in_time >= $t && $out_time > $in_time ) {
                $t = $out_time;
                $phase = 3;
            } else {
                die("\n\nError: Bad time stamp around Data $prevline: $_\n");
            }
        } else {
            die("\n\nError: Bad time stamp format around Data $prevline: $_\n");
        }
    } elsif( $phase == 3 ) {
        if( $_ eq '' ) {
            print(" ");
            $phase = 1;
        } elsif(/^(.+?)\s*$/ ) {
            print("*");
            $_ = $1 . " " x 32;
            print("\n Warning: Void line around Data $prevline: '$_'\n") if $1 !~ /[^\s]/;
        }
    }

    print OUT "$_\n";

}

if( $phase == 1 ) {
    print("\n\n");
    print("---------------------------------------\n");
    print(" $prevline lines processed successfully.\n");
    print("---------------------------------------\n");
    print("$about\n");
} else {
    die("\n\nError: Unexpected end of '$filename'\n");
}

close IN, close OUT;

リンク

この記事のURL


[OGM] SRT日本語字幕 SJIS/UTF-8

2003年 3月 8日
記事ID d30308

OGM動画には字幕を埋め込んで(MUX)、再生時にオンオフできる(ソフトサブ)。 OGMにMUXできる字幕形式は、現状、テキストファイルのSRTのみだ。 OGMは先端の実験的形式なので、SRTに関しても多少の未完成な点や仕様上の混乱があるが、 それをふまえてやれば、充分に実用になる。 不備を回避してSRTの日本語字幕をきれいにMUXする暫定的方法を考える。 SJIS/UTF-8の多字幕(マルチサブ)にもふれる。

再生法やSRT作成の説明でなく、主に、映像・音声・SRTがいちおう用意できた時点からMUXに至るまでの説明です。 またSRT形式の字幕データをハードサブ(永久字幕)として動画内に焼きこむことは可能ですが、 以下で書くのは、より現代的な、再生時に動的にオンオフできるソフトサブ(動的字幕)の話です。

ワードラップ可能な点に半角スペース1個

日本語は、ふつう、英語などと違って単語の切れ目にスペースがない(分かち書きしない)ので、 どこで切っていいのか(どこで改行していいのか)再生時にレンダラーが分からず、 1単位の字幕が1つの長い単語のように認識されて、結果として画面から字幕の両端がはみ出てしまう可能性がある。 そこで、特に短い行以外では、 改行していい場所(文節の切れ目など)に半角スペースを1個入れておくと良い。 適度にスペースがあるほうが字幕も読みやすくなるので、タイプするときに意識的に実行しておく。

切れ目にスペースを入れない例
我が国が誇る最終兵器「おしおきミサイル」は

この例では改行できる場所が明示されていないので、 再生時のフォント設定が大きめだと、行が画面からはみ出てしまう可能性がある。 だからといって最初から固定的に2行にすると、今度は再生時のフォント設定が小さめのとき、おさまりが悪くなる可能性がある。

切れ目にスペースを入れた例
我が国が誇る 最終兵器 「おしおきミサイル」は

この例では、2か所に明示的にスペースを入れているので、 必要ならそこで行の折り返しができる。 フォントサイズ的に一行でいける場合には折り返さない。 改行するかしないか、するとしたらどこでするかは、 再生時のフォントサイズの設定に依存することだからハードコーディングで押しつけず、 再生のときに動的に決めるようにする。 (HTMLの<br>同様みだりに強制改行せず、特に必要ない限り、レンダラーにゆだねる。) プレイヤーやフィルターによっては長い行で自動的に折り返さないものもあるが、 それは作成の問題でなく明らかに再生の不具合であり、 そこまで作成側で付き合う必要ない。 自動ワードラップは、ソフトサブに必要とされる基本の機能であり、 スペースがあっても自動で折り返さないのはプレイヤーが悪い(そのプレイヤーは字幕つきOGMは未対応として避ける)。

通常使用される VobSub では問題ないし、次世代のTCMPでももちろんワードラップする。 SRTでハードコーディングして複数行というのは、 SUB形式(画像だから、あらかじめ適当に改行しておくしかない)から光学文字読み取りで変換してSRTにしていたなごりで、 OGMにMUXするために自分で作成するSRTでは、 ほとんどの場合、同じタイミングの行を手動で2行以上に分ける必要ない。

各行末に64個、半角スペースを

Windows環境で、 OGMの字幕をレンダリングするとき、2003年3月現在、SubtitDS自体のレンダラーでなくVobSubを使うのが一般的だ。 (そのほうが性能も良い。) けれど、バイナリーで0x80-FFを含む文字が字幕にある場合で、 かつ、Windows の言語設定が日本語の場合、 そのままでは各行末の末尾の何バイトかが見かけ上、脱落することがある。 また、脱落が多バイト文字の中間で起きると、多バイト文字の分断による文字化けも発生する。

この現象は、OGMの不具合でなく再生側の不具合であるが、現在、再生時に(システムの言語設定を切り替える以外には)簡単に回避する方法が知られていない。 日本語だから化けるというより、0x80-FFを含むと化けるので、 SRTの言語が英語以外のほとんどの言語で、再生側の Windows の言語設定が「日本語」の場合に発生する。 Windows 2000 でも Windows XP でも発生するようだ。 OS側の言語設定が英語などなら発生しない。 これを回避する暫定手段としては、作成時に、各行末にダミーの半角スペースを挿入しておいて、 見かけ上の脱落がダミーに対して起きるようにする。 BakaSRT Beta ではスペースを32個挿入して日本語でもこれで使えるだろうと書いたが、 試してみたところ日本語の場合、0x80-FFがとても多いので、 (比較的まれにだが)32個ではまだ足らないケースがある。64個または128個を推奨。 ファイルサイズがムダに大きくなるし、いかにも応急処置という感じで気分的に好ましくないが、現在のOGMではやむを得ないことだし、 表示面で特に悪い副作用もない。

この記事の最後に添付したPerlスクリプト BakaSRT Beta2
perl BakaSRT filename 64
とすると filename の各行末に 64 個の半角スペースを挿入した filename_baka.srt が生成される。 この BakaSRT はエラーチェックにもたいへん重宝する。 特にマルチサブでたくさんのトラックをMUXする場合にそうだが、 そうでない場合でも、いちいち再生確認するまでもなく、 明らかなフォーマットの間違いをMUX前に検出、修正できる。

文字コードでUTF-8を使いたい場合

OGG/FLACのタグ(コメント)はUTF-8を使うことになっている。 本来ならSRTもUTF-8にするのが自然だし、多言語対応の点で、再生時の混乱も起きにくかったはずだ。 しかし現在、一般的な(VobSub を利用した)Windows 環境でのOGM再生では、 環境(言語設定)に依存したコードページ(Windows Code Page; Micorosoft Code Page ともいう)、いわゆるCPをを使うようになっている。 西欧語のコードページ(Win Latin)では、フランス語やチェコ語に特有のある種の文字を含む場合 ISO-8859-1 とも UTF-8 とも互換がとれない。 それ以外でも、英語のアルファベットにないウムラウトやアクサンのついた文字、スペイン語やドイツ語やフランス語の特殊文字など、 ISO-8859-1で0x80-FFに入っているものは、UTF-8と互換でない。 また、言語が日本語のときの CP-932 つまり Shift_JIS は、もちろん UTF-8 とは(半角英数字のたぐい以外は)まったく互換性がない。

さしあたっては、 「OGM動画はOGG動画でない」「これがOGMの仕様」と割り切ってOGMとMUXするSRTは、Micorosoft CP を使うのが良いだろう。 日本語の場合、Shift JIS にするのが現実的だ。時代に逆行するようではあるが、現実として受け入れるしかない。 これは日本語に限らず、フランス語やドイツ語でも通常、SRTはUTF-8でなく Win CPなのだから、OGMの仕様としか言いようがない。

そうは言っても、「SJISでは釈然としない、UTF-8でMUXしたい」という要求は、あるだろう。 とくに、UNIX環境でも再生するかもしれない、というとき、せっかくの最新メディア形式でありながら、 Microsoft が決めたコードページに束縛されるのは、気分が良くないかもしれない。 ひとつの解決法というか打開策として、 OGMはマルチトラックなのだから、近い将来にUTF-8を通すフィルターが実用化されることを期待しつつ、 SJIS版とUTF-8版の両方を今からMUXしてメニューで選べるようにしておくことができる。

言語タグのカスタマイズ

日本語の字幕が複数ある場合、それぞれの内容をタギングしておくと良い。

OggMux 0.9.4.2(最新の0.9.4.3ではマルチサブのマックスができないようだ)では、 とりあえず両方 Japanese を選んでおいて、あとから書き換えることができる。 字幕のトラック数が少ないときは、最初から、VirtualDubMod や GraphEdit でやってもたいして面倒ではない。 いずれにしても、VirtualDubMod または GraphEdit で、言語タグを適当に ―― 例えば Japanese (SJIS)Japanese (UTF-8) と ―― タイプして、文字コードが一目で分かるようにしておけば良いだろう。 言語タグに指定した言語名は右クリックしたときのコンテクストメニューなどにそのまま表示される。

VirtualDubMod の例

メニューの OGM | Show Inputs でタグを設定したいストリームを選ぶ。 (最初から VirtualDubMod でMUXする場合は、このダイアログで [Add] をクリックしてファイルの種類をSRTにして読み込む。) ストリームを選択したら、[Comments] をクリック、すでに
LANGUAGE = Japanese
のようなタグがある場合、クリックして、
LANGUAGE = Japanese (UTF-8)
などと Replace する。言語タグがまだない場合は、自分で上のようにタイプして、Add する。

用意ができたら、ぜんぶ Direct Stream Copy で書き出して、目的のOGMを得る。

GraphEdit の例

すでに存在するOGMのオーディオだけ入れ替えたりといった細かいことをするには GraphEdit のほうが視覚的に見通しが良い。 好みによっては、言語タグを打つのも GraphEdit のほうが分かりやすいかもしれない。

GraphEdit を使うには、まず [Ctrl]+[F] を押して、 DirectShow Filters のなかの、 Ogg Multiplexer と、File Writer(出力ファイル名を指定)をロードして結線する。 次に [Ctrl]+[R] を押してレンダーしたいストリームを選ぶ。 OGM自体を開くときは、直接OGMを開く。 AVIコンテナに入れてある映像から新たにOGMを作るには、まず映像を開き、次にオーディオを開き、それらがぜんぶ終わってから、SRTをレンダーする。 言い換えれば、1から数えたトラック番号1(ゼロから数えると Stream 0)に映像、トラック2(Stream 1)以下にオーディオ、オーディオがぜんぶ終わった以下の番号から字幕という順序にする。 現在のOGMのデコーダーは必ずしも柔軟でないので、 作成時にMUXの順序に注意する。

本来、そのトラックがどういう内容なのか再生時にその場でヘッダを読めばトラックの順序などどう追加しても良いはずだが、 個人が実験的に作ったDSフィルターなので、あまり目くじらをたてず、使えるだけでもありがたいと思って、 その仕様に従っておく。先端を切り開いたもののうしろから来て、後追いで細かい問題を指摘するのは、たやすいが、 文句を言えるのも、その実験が存在すればこそだ。 それはそれとして、現実的な注意点として、 1つめの字幕、2つめの字幕……つまり Text Stream 1、Text Stream 2……が、 ビデオ、オーディオ各1トラックのOGMでは、3番目のトラック、4番目のトラック……と字幕自体の順番より2つ大きい番号になる。 しかも、OGM自体ではトラックを0から数えるため、 3番目のトラック、4番目のトラック……にある字幕が、Subtitle 2、Subtitle 3……と表示される。 このようにトラックの番号の付け方が慣れないと分かりにくく、 しかも、再生時の表示として何番の字幕が何なのかも分かりにくい。 先端のものなので仕方ないのだが、マルチサブ用としては、あまりこなれていない。 以上のことを念頭に、作成時には、タグ編集などで間違って1つずれた場所のトラックをいじらないよう、慎重にやる。 なお、不統一なようだが、チャプターは0からでなく1から数えるので、あわせて注意。

ともあれ合体させるぜんぶのストリームをロードしたら、Muxerの四角のうえで右クリックしてプロパティをロード、 あとは、VirtualDubMod の場合と同様に言語タグをカスタムすれば良い。

用意ができたら、再生ボタンをクリックしてレンダリングを開始、目的のOGMを得る。

HTMLタグの互換性

OGMにMUXするSRT内では、<i>タグが使える。 これは字幕が日本語でも問題ない。 挿入歌の歌詞や呪文などを必要に応じて斜字体にすると良いだろう。 ごくまれに、<i>タグがそのまま表示されてしまうという未確認の報告があるが、 事実としたら再生側の環境の問題というべきで、<i>タグはSubtitDSの仕様に明記されていてVobSubにも実装されているので、 OGMでは使いたければ使って良い。

他方、<font>タグは、SubtitDSの仕様には入っているが、VobSub側でサポートしてないので(そのままタグを吐いてしまう)SRTでは使うべきでない。

<b>タグは一部のプレーヤーで区別して表示されるものの、字幕はデフォルトで初めから太字のことが多いので、 一般には、見かけ上、効果が現れない可能性が高い。強調などで他の場所と区別した表示をしたいなら、 <i>のほうが安全だ。ただし、仕様には<u>もある。

ほかの字幕形式(SSA/ASS、USFなど)ならもっと多様な字幕表現が使えるが、 今のところ外部ファイルとしては使えても、OGMでは通常の意味でのMUXができない。

結び

以上みたように、OGMでのSRT日本語字幕は、いろいろ問題はあるし、 「ぎりぎり何とか」という感じもするが、現実的にはちゃんと実用になる。 今の方法は、そもそもがコードページの切り替えという古い方法で、 ユニコードのような平坦な多言語対応とは異なる。 例えば、ドイツ語講座の説明表示の字幕(テロップ)に使おうとしても、 日本語の文字とドイツ語の文字がコードページ切り替えで同じ0x80-FFを共有してしまっているため、 破綻する。これはOGGそのものの制限でなく、OGMの実装のなかで「なりゆきで、そうなった」という部分だが、 将来のOGG動画(もし字幕の標準を決めるなら、 いくら何でもUTF-8をデフォルトにするだろう)との互換を保つうえでも、SRTが英語以外の多くの言語でUTF-8でないのは頭の痛い問題だ。 OGG動画は Ogg Theora モノになって、今のOGMとは結局、つながらないのか、 あるいは、OGGコンテナは結局、漠然とした緩い仕様のままで、字幕の具体的実装方法などに Xiph はタッチしない、 ということでお茶をにごすのでは、 という気さえしてくる。

OGMはもともと個人的な趣味でヨーロッパの人が作ったものだが、 あとからは特に意識的にユニコード対応を打ち出している。 一方、再生側の VobSub では違う伝統に従っている。 SRTそのものは、SubRip(光学文字読みとりを使ってDVD内のイメージ字幕をテキスト字幕にするフリーウェア。 日本語の文字は読みとれない)の形式で、 SubRip は古くからの Windows ソフトで、ユニコードでなく、Windows CP に従う。 結果として Windows CP に従う多くのSRTがOGM内蔵としても出回った。 Windows CP と ISO-8859-1 の差は西欧語では限定的(主にフランス語とチェコ語で使う4文字が影響を受けるだけ)だが、 ISO-8859-1 と UTF-8 は ASCII の部分しか一致しない。 日本語でも、SJISとUTF8は、ほとんどすべての文字、特に漢字かなでは、まったく互換がとれない(一部の半角英数字記号(おおざっぱにはバックスラッシュを除くASCII)のみ互換性あり)。 OGMがかかえるこの問題は、ASCIIだけで足りる英語圏以外では、けっこう面倒で、 新OGG動画では、どうやって後方互換を保証するのか気になるところだ。 Windows CPのどれを「救う」か?いえば、やっぱり第一候補は Win Latin だが、 日本語でそれをやると(OGM→OGGの後方互換フィルターのせいで)また文字化けする。 さりとて、何もせずに WinCP を UTF-8 扱いすれば、これまたひどく文字化けする。 日本語ばかりか西欧語も……。 後方互換性を保つとのコメントは出たものの、 日本語SRTは数も少ないだろうし、せいぜいが「既知の非互換」扱いで終わりかもしれない。 あるいは再生のときに言語エンコーディングを手動?指定するかだが、それだと今とあまり変わらない。 日本語圏でOGM2OGGなツールも出るかもしれないが、それだと結局のところ、字幕のあるOGMはREMUXしないとOGGにならないということで、 後方互換がとれたと言えない。どうするのだろう。確実に言えるのは、とりあえずOGMでは言語タグは打っておいたほうが良い、ということだ。 (安全をとるなら、Shift_JIS の日本語を単に Japanese として、UTF-8 は UTF-8 Japanese とでもしておくのが良い。) しかし、OGM側からみると、何もOGGとの「前方互換」にこだわらず、いま再生できるものはいま再生できる通りのDSFでふつうに再生するのが最善でないかと思われる。 新規作成では、OGMよりOGGのほうが良いかもしれないとしても、作成ソフトも再生ソフトもない現時点では机上の空論で、予測がつかない。

理論的に言うなら、SJIS→UTF-8は、 一対一の変換ですらなく、往復変換ができない (定義域と値域が違うというだけでなくて、 UTF-8にすると同じグリフになるコードポイントがSJISには複数ある。Shift_JISでは、NECとIBM両方のベンダ拡張文字を収録して、 今でもそのままなので、一部の文字が重複収録されている)。 このように、Windows CP-932 は過去のあれこれの結果、複雑につぎはぎになっていて、 リンク先でMS自身が言っているように「この動作は仕様」であり「容易に解決することができない既知の問題」を発生させる。 一見 Windows日本語版のデフォルトとして永続しそうに見えるSJISだが、 実際には Windows日本語版自身、すでに内部的にはUCS-2に乗り換えてしまっている。

OGMについて、Tobias によるOggDSの実装に依存しすぎている、というコメントがよくあるが(じじつそうだが)、 SRTの部分に関しては、OggDS自身より、むしろSubRipとVobSubの実装に依存している。

市販DVDのような透過画像でイメージとして字幕を保持するのに比べれば、 テキストデータを使い再生時にフォントの種類、色、サイズなどを動的に切り替えられるOGMの方法は、より洗練されている。 もちろん、ラクにDVDをバックアップしたいという立場からすればSUB+IDXなグラフィック字幕をそのまま取り込めたら良かったというのがあるだろうが (たぶん日本語に限らず中国語圏などでも……)、 SRTそのものは、それなりに魅力的な世界だ。 字幕作成そのものを趣味とする立場からは、SRTではできることが少なすぎるという単純な批判があるが、 それはハードサブや外部ファイル字幕との比較であるから、 字幕ストリームがMUXできることの意義、その新たな可能性を正当に評価した比較とは言えない。 また、TCMPではすでにサポートが始まったUSFでは、ソフトサブでもSSA/ASSに迫る、あるいは、それを越えることができるのであるから、 ソフトサブそのものが本来的にダメということでもない。 マニアでなく普通に字幕を作れればいい場合でも、 行末の応急処置をはじめOGM内のSRTにはいろいろ不満はあるが、 やはり、 こういうものを最初にやってこれだけできれば充分に高く評価して良く、 ポストAVIの方向性を模索するうえでも、OGMの存在意義は大きかった。

BakaSRT.pl Beta 2

以下の Perlスクリプト bakaSRT Beta 2 は、SRTのエラーチェックを行いつつ、 字幕の末尾に第2引数で指定した個数(省略すると32個)の半角スペースを挿入する。

更新: BakaSRT ver.0.3 では、同じタイミングに対し複数の行が指定されていると警告する。DVDからSubRipでリップした場合、改行が固定されたデータがふつうに発生するが、固定改行はテキストベースのソフトサブの本来でなく、OGMに埋め込むSRTでは一般には好ましくない。特別な意図があれば利用しても良い([動画作成Tips] SRTで特定の行の表示位置を変更)。

BakaSRTをSRTのチェックにのみ利用するときは、挿入空白個数を 0 にすれば良い。 BakaSRTは西欧語の字幕に最適化されており、デフォルトの状態で、 フィンランド語、オランダ語、フランス語、ドイツ語、スペイン語の字幕に対して、動作確認されている。 英語字幕では空白の挿入は(英語字幕のなかのフランス語の単語のような特殊文字がない限り)必要ない。 英語字幕では、念のため 4 で良いだろう。 日本語字幕では引数 64 以上を指定すべきである。

使用法

perl bakaSrt ファイル名 各行末に挿入する空白の個数

各行末に挿入する空白の個数は、省略すると32になるが(大半の言語では32で充分なので)、 日本語の字幕の場合は32では足りない可能性がある。 日本語の字幕では64または128を推奨。

ソース

以下がソースです。コードを読まずに関連リンクへ。

$about = 'BakaSRT.pl beta 2';

if( ! defined($ARGV[0]) ) {
    print("Usage: perl BakaSRT filename [how_many_spaces]\n");
    exit;
}

$filename = $ARGV[0];

if( defined($ARGV[1]) && $ARGV[1] >= 0 ) {
    $num_of_spaces = $ARGV[1] - 0;
} else {
    $num_of_spaces = 32;
}

print "BakaSRT: $num_of_spaces Spaces\n\n";


open IN, "<$filename" or die("Error: Couldn't open '$filename': $!");
open OUT, ">${filename}_baka.srt" or die("Error: Couldn't open '${filename}_baka.srt': $!");

$phase = 1;
$prevline = 0;
$t = -1;

while(<IN>) {
    chomp;
    if( $phase ==1 ) {
        if( /^(\d+)$/ ) {
            if( $1 == $prevline + 1 ) {
                $prevline++;
                $phase = 2;
            } else {
                die("\n\nError: Bad line number around Data $prevline at $filename\n");
            }
        } else {
            print("\n Warning: Bad format around Data $prevline at $filename\n");
        }
    } elsif( $phase == 2 ) {
        if( /^(\d\d)\:(\d\d)\:(\d\d)\,(\d\d\d) \-\-> (\d\d)\:(\d\d)\:(\d\d)\,(\d\d\d)$/ ) {
            $in_time = $1 * 3600 + $2 * 60 + $3 + $4/1000.0;
            $out_time = $5 * 3600 + $6 * 60 + $7 + $8/1000.0;

            if( $in_time >= $t && $out_time > $in_time ) {
                $t = $out_time;
                $phase = 3;
            } else {
                die("\n\nError: Bad time stamp around Data $prevline: $_\n");
            }
        } else {
            die("\n\nError: Bad time stamp format around Data $prevline: $_\n");
        }
    } elsif( $phase == 3 ) {
        if( $_ eq '' ) {
            print(" ");
            $phase = 1;
        } elsif(/^(.+?)\s*$/ ) {
            print("*");
            $_ = $1 . " " x $num_of_spaces;
            print("\n Warning: Void line around Data $prevline: '$_'\n") if $1 !~ /[^\s]/;
        }
    }

    print OUT "$_\n";

}

if( $phase == 1 ) {
    print("\n\n");
    print("---------------------------------------\n");
    print(" $prevline lines processed successfully.\n");
    print("---------------------------------------\n");
    print("$about\n");
} else {
    die("\n\nError: Unexpected end of '$filename'\n");
}

close IN, close OUT;
日本語字幕(ソフトサブ)OGMサンプル
関連記事

この記事のURL



<メールアドレス>