5 : 20 動画をHTMLに埋め込むヒント

← 5 - 19 p↑ もくじ i 5 - 21 n →

新種ブラクラ: 画像の表示だけでIEがクラッシュ

2002年 5月 4日
記事ID d20504a

XBM画像の扱いに問題

IE5.5以上またはOE5以上を簡単にクラッシュさせる新種のブラクラが報告されました。画像を表示しようとするだけでフリーズするので、通常のセキュリティレベルの設定では、ふせげません(画像を非表示にすればふせげます)。

この問題は、最新のIE/OEが、XBM画像を表示できることに関係しています。XBM(X Bitmap)画像はテキスト形式で、次のようなヘッダを持っています。

#define 画像名_width 画像の幅
#define 画像名_height 画像の高さ

IE/OEは、このヘッダを「すなお」に解釈して指定の高さと幅のビットマップを生成すべくメモリを確保します。悪意、または、おちゃめで、とんでもない数値(例: 100億ピクセル×100億ピクセル)を書くと、IEはメモリの確保に失敗しクラッシュします。詳細については、以下を参照。

次にあげるのは、ごく小さな(2KB)、正常なXBM画像の例で、IE5.5以上のほか、Netscape 4.7x や Opera 6.x でも表示可能です。(Mozilla では表示できないもよう)

見かけは2色の透過GIFのような画像

この画像の「ソース」は次のようなテキストです。

#define unyu_width 48
#define unyu_height 48
static unsigned char unyu_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0D, 0x00, 0x00, 0x18, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x40, 0x00, 0xE0, 0x01, 0x00, 0x80, 0x81, 0x00, 0xFE, 0x03, 0x80, 0x81, 0x9F, 0x00, 0x3C, 0x00, 0xE0, 0x00, 0x1E, 0x01, 0x18, 0x00, 0x7C, 0x00, 0x00, 0x01, 0x30, 0x00, 0x08, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0x02, 0x60, 0x00, 0xE0, 0x00, 0x1E, 0x02, 0x70, 0x00, 0x60, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0xC6, 0x06, 0x08, 0x78, 0x00, 0x60, 0xFE, 0x03, 0x08, 0x78, 0x00, 0x00, 0x1C, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7E, 0x00, 0x06, 0x3C, 0x00, 0x20, 0x7E, 0x00, 0x7C, 0xE6, 0x03, 0x20, 0xFE, 0x00, 0xE2, 0x03, 0x06, 0x20, 0xFE, 0x00, 0x06, 0x00, 0x04, 0x60, 0xFE, 0x00, 0x3C, 0x00, 0x04, 0x60, 0xFE, 0x01, 0xF0, 0x03, 0x04, 0x40, 0xFE, 0x01, 0xC0, 0x03, 0x04, 0x40, 0xFE, 0x03, 0x00, 0x07, 0x02, 0x40, 0xFE, 0x07, 0x00, 0xFE, 0x01, 0x40, 0xFE, 0x07, 0x00, 0x7C, 0x00, 0x40 };

アパッチはデフォルトで Content-Type: image/x-xbitmap として、.xbmファイルをサポートしています。

類似の現象は、Mozilla が SVG 形式の画像を解釈しようとした場合にも発生する可能性があるように思います。

参考

この記事のURL

テキスト版省パケ版XML版


Flash Playerにセキュリティホール、最新版で修正

2002年 5月 4日
記事ID d20504

バグが修正された最新版は6.0.29.0

Windows IE用の Flash Player に重大な欠陥

2002-05-04 アドビと「あーっ、勝手にまねしたなー」と互いに非生産的な訴訟を起こしあっているマクロメディアですが(ユーザが払ったソフト代金は高額の訴訟費用にばけ)、Windows版IE用の Macromedia Flash Player に重大なセキュリティーホールが発覚しました。デフォルトの設定の場合、リモートからブラウザ経由で任意のコードを実行できる、という致命的なものです。詳細は、バグトラックをごらんください。リンク先に書いてあるように、すでにバグフィックスされた最新版が出ています。

歯車のアイコン 不具合が見つかったのは、フラッシュプレーヤーをウェブページにうめこむのに使う flash.ocx(アクティブXコントロール)というフラッシュのコンポーネント。それの古いバージョンがバッファオーバーフローを起こすと報告されています。ファイルバージョンを確認するには、システムフォルダーの Macromed¥Flash あたりを見てください。現在の最新版6.0.29.0以降ならば問題ないです。日本語版もすでにリリースされています。最新版をダウンロードするには、ダウンロードセンター日本語版)をおとずれてください。そのさい、IEの設定でActiveX関係が有効になっている必要があります。

なお Windows ユーザでもネスケ用の Flash Player しかインストールしてない場合には、影響を受けません。IE用の古いフラッシュがインストールされているかどうか確認するには、ファイル名 flash.ocx で検索してください。もしあればインストール済みということになります。ネスケユーザなども、念のために(ネスケ版Flashを)最新版にバージョンアップしとけば間違いないです。

この記事のURL

テキスト版省パケ版XML版


動画をHTMLに埋め込むヒント

2002年 5月 3日
記事ID d20503a

動画を MediaPlayerコントロールとしてHTMLにうめこむ場合のヒントとして、「ActiveXが使えない環境でも困らない」「ActiveXをオフにしている環境で警告ダイアログが出ないようにする」「停止状態で動画中のひとこまが静止画で見えるようにする」という3つの Tip を説明します。アクティブスクリプトについての予備知識を前提とします。

何が問題か

現在、動画のファイルをウェブで公開する場合、そのファイルへのリンクという形にしていることが多い。しかし、次の図のように(ふつうのイメージと同じように)ページ内に画像を埋め込みたい場合もある。(以下は動画コントロールの例の画像で、これ自体は、ホンモノのコントロールでありません。説明のためのただの絵です。)

PNG画像

動画再生用のコントロールが埋め込まれたページの例

つまり、映画やアニメについてのレビューを書くような場合、ウェブページの内部に、引用したクリップを再生できる小さな窓があれば、引用箇所とその部分についてのコメントを見比べやすく、分かりやすい記事になるだろう。また、何かの説明に動画を用いる場合も、説明の文章と動画がすぐそばに並んでいるほうが、見やすいだろう。外部リンクにしても本質は同じだが、いちいちほかのヘルパーアプリのウィンドウを見なくても、ウェブページそのものの内部に画像が「ペースト」されていたほうがべんりだし、そのほうがウェブページのマルティメディアとしてのポテンシャルが発揮される。

けれど、この方法には、いくつかの注意点がある。

  1. 上のような埋め込みは、MSIEでしか有効でない。IE以外でも有効な暫定的な「embed」方式もあるが、廃止予定と分かっているので(=古いブラウザでしか見れなくなる)、積極的に使う気には、なれない。
  2. MSIEでも ActiveX が有効になっていないと機能しない。単に機能しないだけでなく「ActiveXがオフなので正しく表示できません」という意味のダイアログがいちいち出る。ActiveXをオフにしている読者にとって、うざいページになってしまう。
  3. ActiveX が有効になっていても、ふつうの方法では、ページを開いたときに再生用の窓が真っ黒だったり、あるいは Windows のロゴが表示されていて、あまり良くない。むしろページを読み込んだ段階で、再生可能な動画のなかの1カットが静止画として表示されたほうが好ましいと思われる。(上の図版では、まさにそのようになっている。)

そこで、以下では、次のことがらについて説明する。

  1. ブラウザに依存せず、しかもembedのような廃止予定の方法でもなく、プレゼンテーションを行えるようにする方法。
  2. MSIEで ActiveX が無効になっているユーザに対して、いちいちうざい警告を出さないようにするハック。
  3. MSが予想している使い方に反して、初期に任意の1カットの静止画が表示されるようにするハック。

ActiveX がなくても問題ないようにする

基本的に <object> を使って、必要な ActiveX が利用可能なら動画の埋め込み、無効なら代わりのイメージが表示されるようにする。いずれの場合でも、動画へのリンクを作っておく。ActiveX が無効の場合、直接リンクがないと動画にまったくアクセスできなくなってしまうから、その場合にリンクが必要になることは言うまでもない。けれど、IEで埋め込みが可能でも、動画をローカルにダウンロードしたり、なんらかの理由で埋め込みの窓より外部のヘルパーアプリを使いたい場合もあるだろうから、ActiveX が使える場合でも、リンクもあるほうが良い。概念的には、次のような感じになる。

<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95">
<!-- ActiveX が有効なら、次のパラメータで埋め込まれる -->
<param name="FileName" value="clip.wmv" />

<!-- ActiveX が無効なら、次のタグが解釈される -->
    <img class="inset" src="clip1.jpg" width="160" height="120" alt="愛国戦隊大日本" />
</object>

<!-- 直接リンク -->
<p>
Windows Media Video 8形式の動画クリップ 263KB:
<a href="clip.wvx">ストリーミング(64Kbps)</a>, 
<a href="clip.wmv">非ストリーミング</a>
</p>

なにをもって最善とするかは価値観の問題だが、この方法は、ぶなんなソリューションだろう。

上記の classid は古いほうの mplayer2.exe(MediaPlayer6)に対するものです。新しいほうの MediaPlayer の場合は、
CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
という値になるらしいが、手元ではうまく動かないし、mplayer2 のほうが軽いので、さしあたっては、これを使ってみました。

ActiveXをオフにしているIEで警告を抑止する

ActiveX を原則オフにしているかたならよくご存じと思うが、ActiveXがオフだと、ある種のコントロールを含むページを開くたびごとに次のような警告ダイアログがいちいちポップアップして、たいへんうざい。

「現在のセキュリティの設定では、このページの ActiveX コントロールは実行できません。そのため、このページは正確に表示されない可能性があります。」

上記のような動画のプレゼンテーションにおいては、ActiveX が有効であってくれたほうが、つごうがいい。けれど、だからといって、ActiveX が無効のユーザに対して、こんないやがらせのような警告をポップアップさせるのは、行儀が悪すぎる。このポップアップは、それとなしに ActiveX がオンでないのが悪いとほのめかしているが、オフならオフでかまわない。オフであるかもしれないことも考慮して、その場合でも、機能の低下が整然としたものになるようにするべきだ。

けれど、このポップアップは、IE(ないしWindows)自身が勝手に出すものなので、ウェブライターの側から直接、抑止できない。そこで、ActiveX がオフであれば、初めからこの <object> タグを見せないようにしよう。 <object> があると「オフだからダメです」と言われることが分かっているときには、 <object> を読ませない。そうすれば、うざい警告も出ない。

そのためには、まず ActiveX が有効か無効か調べて、有効な場合だけ、これらのソースを書き出せば良い。それには JavaScript が必要だが、JavaScript がオフになっているとしたら、たいがい ActiveX もオフになっているだろうから、JavaScript がオフの場合、つまり <noscript> が解釈される場合には、ActiveX は利用できないと仮定してしまって実用上、問題ないだろう。

したがって、問題は、ActiveX が有効かどうか、クライアント側スクリプトでどのように検出すればいいか?につきる。

navigator.javaEnabled() メソッドのような感じで、navigator.activeXEnabled() みたいなのが JScript の独自拡張にあれば速いが、そんなのがあるのかどうか、よく分からない。ここでは、次のような強引なハックを使う。すなわち――

  1. _ActiveX = false から始める。
  2. IE5以上らしき場合、ActiveX が使えるかどうか知るために、試しに
    ActiveXObject("Microsoft.XMLHTTP")
    を実行する。ここで生成する XMLHTTPオブジェクトには、まったく意味がなく、生成できるかどうか試すだけの目的である。
  3. もし生成できれば、そのまま平和に _ActiveX=true を評価させる。
  4. 生成できないときは例外が発生するので、それを逆用して、ダミーの catch 節にジャンプさせる。すると、後続する _ActiveX=true が評価されない。したがって、_ActiveX = false のまま。

以上のアイディアを実装するにあたっては、IEのふりをするOperaを排除するように気をつけなければいけない。ただのIEエミュにすぎないOperaは、上のような強引なハックにたえられず、最悪フリーズしてしまう。Operaの場合、上記のチャレンジをスキップさせなければならない。以下のリストは、完全ではないが、ほぼ実用になるのでは……。IE以外や、IEでもActiveX が無効の場合には、平和に静止画が出力され、ActiveX が有効な場合のみ埋め込みが実行されるので、うるさい警告が出る可能性が低くなる。

var _ActiveX = false;
var _Opera = false;

for(var i=0; i<navigator.plugins.length; i++){
    if( (navigator.plugins[i].name.toLowerCase()).indexOf("opera")>-1 ) {
        _Opera = true; // Opera6
    }
}

var ua = navigator.userAgent.toLowerCase();

if( ua.indexOf("opera") > -1 ) _Opera = true;

if( document.all && ua.indexOf("msie 4") < 0 && !_Opera ) { // MSIE5, 6...
    var hack = 'try{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");'
        + '_ActiveX=true;}catch(e){}';

    execScript( hack );
}

var d = document;

d.write('<div class="clip">');

if( _ActiveX ) {
    d.write('<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95">');
    d.write('<param name="FileName" value="clip.wvx" />');
    d.write('<img src="clip.jpg" width="160" height="120" alt="" />');
    d.write('</object>');
} else {
    d.write('<img src="clip.jpg" width="160" height="120" alt="" />');
}

d.write('</div>');

この発想は真にエレガントでないし、試しに作ってみるオブジェクトが XMLHTTP というのも行き当たりばったりの感じだが、とりあえず、これで動く。もっと良い方法が見つかったら改訂します。良いアイディアがあったらこのへんに書いてください

概念を理解するためのスケルトン
<script type="text/javascript">
var _ActiveX = false;
var _Opera = false;
function _debug( msg ) {
    document.write("<p>Debug: " + msg + ".</p>");
}

for(var i=0; i<navigator.plugins.length; i++){
    if( (navigator.plugins[i].name.toLowerCase()).indexOf("opera")>-1 ) {
        _Opera = true; // Opera6
    }
}

var ua = navigator.userAgent.toLowerCase();

if( ua.indexOf("opera") > -1 ) _Opera = true;

if( document.all && ua.indexOf("msie 4") < 0 && !_Opera ) { // MSIE5, 6...
    var hack = 'try{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");'
        + '_ActiveX=true;_debug("ActiveX Enabled");}'
        + 'catch(e){_debug("ActiveX Disabled");}';
    execScript( hack );
} else {
    _debug("Not MSIE");
}
</script>
<noscript>
<p>Debug: No script.</p>
</noscript>
実際に実行する

停止状態で静止画を表示させる

そんなこんなで、無事コントロールが表示されても、デフォルトのままだと、動画の表示部分が真っ黒だったり、次のように Windows のロゴが表示されている。

広告のようなロゴがうざい。

同じプレイスホルダなら、Windows のロゴなどより、初めにあげた例のように、「そこで再生可能な動画のなかのワンシーン」が静止画で出ているほうが好ましいだろう。

それを直接、指定できるパラメータもあるのかもしれないが、とりあえず以下の方法を試したらできたので、紹介します。

まず、パラメータで、
<param name="TransparentAtStart" value="true" />
を与えて、背景を透過させる。そのうえで、<object> の style属性で好きな背景画を指定する。ただそれだけです。

いちいち説明するより、以下のリストを見たほうが速いでしょう。

d.write('<object id="clip1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95"');
d.write(' type="application/x-oleobject" width="155" height="115"');
d.write(' style="border: inset thin; background-image: url(clip1.jpg)">');
d.write('<param name="FileName" value="clip.wvx" />');
d.write('<param name="AutoStart" value="false" />');
d.write('<param name="TransparentAtStart" value="true" />');
d.write('<param name="AutoSize" value="true" />');

d.write('<param name="ShowAudioControls" value="true" />');

d.write('<param name="ShowPositionControls" value="false" />');
d.write('<param name="ShowTracker" value="false" />');

d.write('<param name="AutoRewind" value="true" />');
d.write('<img src="clip.jpg" width="160" height="120" alt="" />');
d.write('</object>');

ここで object が読み込めなかったときに表示されるイメージと同じ静止画を object の背景に指定しておくと、ActiveX が使えた場合も使えなかった場合も同じようなページレイアウトになり、単に埋め込み機能が使えるか使えないか?だけの違いとなる。

このほか AnimationAtStart パラメータを false (既定値は true)にすると、再生ボタンを押してから再生が始まるまでの読み込み中に Windows のロゴが出るのも抑止できます。ブロードバンドの場合、そのほうがすっきりして良いでしょう。ナロウバンドの場合、このパラメータを false にすると読み込み中に画面が真っ黒な状態がつづいて不安になるので、ここでは既定値のままにしてあります。パラメータについての詳細は、Streaming Mpeg-4 from Your Website がたいへん参考になりました。

まとめ

必要なスクリプトを clip.js として、実際のHTMLは、次のような感じになる。

<script type="text/javascript" src="/image/2002/aikoku/clip.js"></script>
<noscript>
<div class="clip">
<img src="/image/2002/aikoku/clip.jpg" width="160" height="120" alt="" />
</div>
</noscript>

コードを実際にペーストしておくので、いろいろなブラウザで見てみてください。お気づきの点がありましたらおしえてくださいね

実際に利用可能なコントロールとリンクです。64Kbps未満の帯域の場合は、完全にダウンロードしてから再生する非ストリーミング再生をご利用ください。

DAICON FILM「愛国戦隊大日本」(1982)より

Windows Media Video 8形式の動画クリップ 263KB: ストリーミング(64Kbps), 非ストリーミング

ActiveXコントロールが利用可能な環境では、次のように表示されるはずです。

プレーヤーが埋め込まれる。

(これは画像です。)

ActiveXコントロールが利用できないか、またはJavaScriptがオフになっていると、埋め込みコントロールのかわりに、同じ静止画がふつうに img で表示されます。「ActiveXが使えないので正しく表示できない」という警告ダイアログも出ず、ここに ActiveX を埋め込もうとしたという形跡自体が隠蔽されます。動画ファイルへのリンクのそばに、その動画の一場面のイメージが貼ってあるようにしか見えません。

同じ場面が静止画で表示される。

以上のように、スクリプトを駆使することで、ActiveX が使えない場合の機能の低下を、整然としたものにすることが可能です。いずれの場合でも動画ファイル(この例ではWMV)ないしメタファイル(WVX)への直接リンクを利用でき、ActiveX が有効であればさらにページ内の埋め込み再生も利用できる、ってわけです。

動作確認: Windows 2000 SP2 + IE6 / Mozilla 1.0RC2 / Netscape 4.79 / Opera 6.02 build1090(Operaは不安定)

なお、.htaccess 等で設定すべき mimeタイプは、次のとおりです。

AddType audio/x-ms-wma .wma
AddType video/x-ms-wmv .wmv

AddType audio/x-ms-wax .wax
AddType video/x-ms-wvx .wvx

ちなみに、ここでは使いませんが、<embed> タグを利用しつつもHTML4.01の仕様書に反しないようにする方法もあります。document.write のなかの文字列として扱えば良いわけです。Jpeg2000 の場合などどうしても <embed> が必要だけれど形式的には仕様書は守りたい、という考えの場合には、そういう方法も良いかもしれません。

愛国戦隊をめぐる記事を書こうとして、動画をページにうめこみたいと思ったら、上のような技術的問題に気づいたので、まず、それをいちおう解決したしだいです。本題の「愛国戦隊」論は、このあとに続きます。

リンク

この記事のURL

テキスト版省パケ版XML版



webmaster@faireal.net