Flash Player とブラウザのバージョン判定するスクリプト

とある要件で、Flash Player とブラウザのバージョン判定する必要があったので、簡単なスクリプトを作りました。Flash Player のバージョンは Flash 側で判定して JavaScript 側に値を送り込む仕様になっています。スクリプト自体は非常に簡単です。
※Flash というか Action Script は相変わらず肌に合わず、ド素人状態でございます・・・(;´д`)ゞ

まずは実行サンプル(このリンクをクリックしてください)。正しく実行されていれば、下記ように Flash Player とブラウザのバージョンが表示されているはずです。

- スポンサーリンク -

ok001.png

スクリプトのソースコードはこんな感じです。まずは Action Script 側です。単純に getURL() 関数で JavaScript 側の関数を呼び出しているだけです。関数名はハードコーディングで getFlashVersion() 固定で実装しています。なので JavaScript 側で getFlashVersion() 関数を定義してあげる必要があります。
※FlashVerCheck.fla (右クリック保存でダウンロードできます)

getURL("javascript:getFlashVersion('" + getVersion() + "');");

getURL() 関数を使った場合は簡単で下位互換性も十分にあって安心設計なのですが、ローカルでテストしようとするとセキュリティー的に問題があることから実行することができません。たとえば FireFox とかだとこんなエラーが出てしまいます。

err001.png

もちろんサーバ上にアップして確認する場合には、上記ようなエラーは発生しませんが、テスト時に若干面倒ですよね。それで、こんな実装をしてみたのですが旨く動かないブラウザとかがあったりと、よくわからなかったので断念しました。

import flash.external.*;
import flash.net.*;

var callJasFunction:String = "getFlashVersion";
var msg:String = getVersion();
try {
    ExternalInterface.call(callJasFunction, msg);
} catch(e:Error){
    trace(e); // エラー内容を出力
}

次に html 側の実装です。スクリプトのソースはこんな感じです。
Flash 側から getFlashVersion() 関数が呼び出されて、引数として渡された Flash Player のバージョンを解析して hidden 値として記憶します。ついでに OS 環境とメジャーバージョン値とマイナーバージョン値も分割して保持します。
次に getFlashVersion() 関数から getBrowserVersion() 関数が call されてブラウザ環境を判定します。この部分は他でも使い回しが効くと思います。
最後に setTimeout() 関数を使って、一連のバージョン取得が終わったであろう時間(100ミリsecにしておきました)に version_check() って関数を呼び出して、最後の判定処理を記述しています。実要件では、この関数内に必要な処理を各イメージです。
※サンプル.html (右クリック保存でダウンロードできます)

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="versionCheck" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="FlashVerCheck.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="FlashVerCheck.swf" quality="high" bgcolor="#ffffff" width="1" height="1" name="FlashVerCheck" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://get.adobe.com/jp/flashplayer/" />
</object>

<form>
<input type="hidden" name="flash_version_os" value="">
<input type="hidden" name="flash_version_ver" value="">
<input type="hidden" name="flash_version_ver_major" value="">

<input type="hidden" name="browser_type" value="">
<input type="hidden" name="browser_version" value="">
</form>

<fieldset><legend>あなたの Flash Player 環境は以下の通りです。</legend>
<blockquote>
<div id="log1"></div>
</blockquote>
</fieldset>

<fieldset><legend>あなたのブラウザ環境は以下の通りです。</legend>
<blockquote>
<div id="log2"></div>
</blockquote>
</fieldset>

<div id="log3"></div>

<script>

// Action Script から呼び出される固定の関数名です
function getFlashVersion(version) {
    if (!version) {
        return;
    }
    var data = version.split(/\s/);
    var ver = data[1].split(/,/);
    var os = data[0].match(/^WIN/) ? 'win' : 'other';
    var ver_major = ver[0];

    document.getElementsByName("flash_version_os")[0].value = os;
    document.getElementsByName("flash_version_ver")[0].value = version;
    document.getElementsByName("flash_version_ver_major")[0].value = ver_major;

    var log = document.getElementById("log1");
    log.innerHTML = "os=" + os + "<br>ver=" + ver_major;

    getBrowserVersion();
}

function getBrowserVersion() {
    var userAgent = navigator.userAgent.toLowerCase();
    var version = (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)) ? RegExp.$1 : '';
    var safari = (userAgent.match(/webkit/)) ? 1 : 0;
    var opera = (userAgent.match(/opera/)) ? 1 : 0;
    var msie = (userAgent.match(/msie/) && !userAgent.match(/opera/)) ? 1 : 0;
    var mozilla = (userAgent.match(/mozilla/) && !userAgent.match(/(compatible|webkit)/)) ? 1 : 0;
    var browser = msie ? 'msie' : mozilla ? 'mozilla' : safari ? 'safari' : opera ? 'opera' : 'unknown';

    document.getElementsByName("browser_type")[0].value = browser;
    document.getElementsByName("browser_version")[0].value = version;

    var log = document.getElementById("log2");
    log.innerHTML = "browser=" + browser + "<br>ver=" + version;
}

function version_check() {
    var log = document.getElementById("log3");
    var msg = new Array();
    if (document.getElementsByName("flash_version_os")[0].value != 'win') {
        msg.push("Windows 環境じゃないので対象外です。");
    }
    if (document.getElementsByName("flash_version_ver_major")[0].value < 7) {
        msg.push("Flash のバージョンは 8 以上が必要です。");
    }
    if (document.getElementsByName("browser_type")[0].value == 'msie' && document.getElementsByName("browser_version")[0].value < 6) {
        msg.push("ブラウザが対象外のバージョンです。");
    }
    var errormsg = msg.join("<br");
    if (errormsg) {
        log.innerHTML = "以下の条件を満たしておりません。<br><blockquote>" + errormsg + "</blockquote>";
    } else {
        log.innerHTML = "想定する環境を満たしております";
    }
}

// Flash が実行されたであろうタイミングで実行してあげる
setTimeout(function() { version_check() }, 100);

</script>

若干手抜きになっていますが、version_check() 関数内で hidden 値が NULL だった場合の処理とかを追加すれば、Flash 側から getFlashVersion() が実行されなかった判定とかも記述できるかと思います。

と、ここまで書いておきながらネットで情報を検索してみると、Adobe が公式判定方法?を公開していました。勉強になりました。でもちょっと面倒くさい気がしますが・・・。

Flash Player 10 バージョン判別チェックリスト | デベロッパーセンター

バージョン判別のベストプラクティス?
一部気になる点はありますが、もっとも安定して判別できるのは、やはり「SWFObject」を使用した方法ではないかと思います。
事実、最新の Dreamweaver CS4 で書き出される HTML への SWF ファイルの埋め込み方法には SWFObject 2.0 が正式採用されています。
もちろん、今後もブラウザや Flash Player のバージョンアップは想定されますし、Google Chrome のような新しいブラウザの登場も十分考えられますので、永続的にこの方法がベストプラクティスであるとは言い切れません。しかし「SWFObject」はオープンソース・コミュニティに支えられ、今後もそのような変化に柔軟に対応していくものと思われます。

その他、JavaScript だけで判定する手法とかも見つかりますが、旨く動作しないものが多いようです。(OS などが新しくなったりする度にメンテしないといけないらしい・・・)

→Flash javascript バージョン 判定 - Google 検索 で他の手法も探してみるばあいはこちら。

- スポンサーリンク -