13新卒エンジニアの古川です。今回が初めての投稿です!よろしくお願いします。
今回はAJAX通信入りFlash動画をJSに変換することが可能なのか、実際に検証した内容を記事にしました!
実際に試したツール
・Google Swiffy
Googleが提供しているFlash動画をSVGに変換してくれるサービスです。
https://www.google.com/doubleclick/studio/swiffy/
・CreateJS
Adobeが提供しているFlash Professional用のアドインで、Flash動画をHTML5のCanvasとJavascriptに変換してくれるツールです。
http://www.createjs.com/
検証に使ったFlash動画
まず最初に、この画面が表示されます。
そのあと、Ajax通信で取得した値をもとに、次のように「晴れ!」か「雨...」を表示させます。Ajax通信で取得できる値は0~100のランダムな数字です。この値が0~50の場合は晴れを表示して、51以上は雨を出す感じですね。
0~50 の場合
なお、Flashのシーンについては、「晴れを表示するシーン」と「雨を表示するシーン」に分けることにします。
Google Swiffyで変換に挑戦
まずはこちらのActionScriptで実装してみました。URLRequestクラスを使った方法です。
1フレーム目:
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
stop();
var myRequest:URLRequest = new URLRequest("http://example.com");
myRequest.method = URLRequestMethod.GET;
myRequest.data = new URLVariables();
var myLoader:URLLoader = new URLLoader();
myLoader.addEventListener(Event.COMPLETE, onComplete);
myLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
myLoader.load(myRequest);
function onComplete (eventObject:Event):void
{
// 読み込んだデータを取得
var ret:int = eventObject.target.data;
trace(eventObject.target.data);
if(ret <= 50){
gotoAndStop("1", "シーン 1");
}else{
gotoAndStop("2", "シーン 2");
}
play();
}
function onError(e:Event):void {
//エラー処理
}
このActionScriptを含んだFlashをswf形式にエクスポートし、GoogleSwiffyで変換してみました。
しかし、変換は無理でした。理由はURLRequestクラスが対応していない模様・・・
今度はActionScript2.0で使われるLoadVarsクラスを試してみました。
1フレーム目:
stop();
myVars = new LoadVars();
myVars.onLoad = function(result) {
var val:int = parseInt(result);
if (val<= 50) {
gotoAndStop("2", "シーン 2");
play();
} else {
trace("try again");
}
}
myVars.sendAndLoad("http://example.com", myVars, "GET");
結構古い方法だからいけるはず、、、
と思ったらこれも変換に失敗しました。どうやらLoadVarsクラスが対応していない模様です。
今度はJavascriptで通信処理を行う方法ならどうですかな?
1フレーム目:
import flash.external.ExternalInterface;
stop();
var ret:int = -1;
if( ExternalInterface.available ) { //一応ExternalInterfaceが使えるかを確認
try{
ExternalInterface.call("getHTTP");
ret = ExternalInterface.call("getValue");
if(ret <= 50){
gotoAndStop("1", "シーン 1");
}else{
gotoAndStop("2", "シーン 2");
}
play();
}
catch(e:Error){
//それ以外のエラーが起きた場合(同じくエラーメッセージを出力するとか)
}
}
HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<script>
var ret = -1;
function getHTTP(){
$.ajax({
type: "GET",
url: "http://example.com",
data: "",
success: function(msg){
ret = msg;
}
});
}
function getValue(){
return ret;
}
</script>
</head>
<body>
<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,0,0"
WIDTH=300 HEIGHT=300>
<PARAM NAME=movie VALUE="sample.swf">
<PARAM NAME=bgcolor VALUE=#FFFFFF>
<PARAM NAME=LOOP VALUE=false>
<PARAM NAME=quality VALUE=high>
<EMBED SRC="sample.swf" WIDTH=300 HEIGHT=300 bgcolor=#FFFFFF allowScriptAccess="always" LOOP=false QUALITY=high
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"
TYPE="application/x-shockwave-flash" </EMBED>
</OBJECT>
</body>
<html>
しかし、これも変換に失敗しry。。。。ってGoogle Swiffy 未対応大杉ww
「これ無理じゃね?」と感じてチーフに相談しましたところ、、「外部からパラメータを渡して実行してみればどうかな?」とヒントをいただきました。
なるほど~じゃあ、実装してみるか!という感じでチャレンジ
こんな感じになりました。
1フレーム目:
stop();
var obj:Object = loaderInfo.parameters;
if ( obj["ret"] ) {
var parameter:int = parseInt(obj["ret"]);
if(parameter <= 50){
gotoAndPlay(1, "シーン 1");
}else{
gotoAndPlay(1, "シーン 2");
}
}
HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<object
type="application/x-shockwave-flash">
<param name="movie" value="sample.swf" />
<param name="FlashVars" value="ret=60" />
<embed src="sample.swf">
</object>
<html>
これは・・・通過しました!
その後、変換後のHTMLファイル上のscriptタグに対して次のように変更。Ajaxで通信処理!
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$.ajax({
type: "GET",
url: "/return_json",
data: "",
success: function(msg){
ret = msg;
var stage = new swiffy.Stage(document.getElementById('swiffycontainer'),
swiffyobject);
stage.setFlashVars("ret="+ret);
stage.start();
}
});
</script>
これを実際に実行。
1回目
晴れ!
雨出るまで更新を繰り返す・・・
出た!!!
見事に動きました。
次にスマホ実機テスト。だがしかし、ここで思わぬ罠が・・・・
Android2シリーズが未対応・・・
どうやらAndroid2はSVGに対応していなかった模様。。
なお、Android2.3は今でもシェア率40%以上のため、Google Swiffyは却下
1日を無駄にしてしまったOTL
CreateJSで変換に挑戦
Google SwiffyはAndroid2が未対応だったが、、このツールならどうかな?そんな感じで実装に挑戦!
とりあえずいつものActionScriptを・・・
1フレーム目:
stop();
var obj:Object = loaderInfo.parameters;
if ( obj["ret"] ) {
var parameter:int = parseInt(obj["ret"]);
if(parameter <= 50){
gotoAndPlay(1, "シーン 1");
}else{
gotoAndPlay(1, "シーン 2");
}
}
変換して実行!
あれ、動かない・・・・・
なんでだろう、と原因を調べていました。
このツールを使ったことある人はご存知ですが、
実はActionScriptではなく、Javascriptでアニメーションを操作する。(ActionScriptをJavascriptに変換してくれると思ったら大間違いだったのですね・・・
はじめての人は嵌るかもしれないので注意が必要。
というわけで、これにめげずJavascriptで実装していきました。
作ったソースがこのとおり。
1フレーム目(「/* js」という形でコメントアウトをつけると、変換時にJavascriptを埋めてくれる)
/* js
var main = this;
main.stop();
$.ajax({
type: "GET",
url: "/return_json",
data: "",
success: function(msg){
ret = msg;
if(ret <= 50){
main.gotoAndPlay(0);
}else{
main.gotoAndPlay(120);
}
main.play();
}
});
*/
110フレーム目
/* js
stop();
*/
また、ここで使用している動画はもともとシーンを2つに分けていましたが、CreateJSは複数のシーンに対応していません。ですので、次のように2つのシーンをひとつにまとめました。
1~110 晴れを表示するシーン
120~240 雨を表示するシーン
あ、あとjQueryのAjax使ってるので、それのロードも忘れないように!
パブリッシュし、開発サーバに放り込んでテストしてみました。
1回目
雨!
晴れが出るまで更新を繰り返す・・・
出た!!!
お~動いた!
あとは気になるAndroid2シリーズの対応はというと・・・こんな感じです。
Android2.1×
Android2.2○
Android2.3○
これなら問題なく使えるね!
結論
結果的にどちらのツールでも実現できましたが、今の現状、Android2.3のシェア率が高いので、通信処理を含むフラッシュ動画をJSに変換するツールはCreateJSが最適ということがわかりました。Android2.3はそのうちシェア率が減ってきますので、Android4が主流になったときはGoogle Swiffyもありです。
※CreateJSにはシーンがひとつしか使えないだけでなく様々な制約があるため、高度なエフェクトを使う場合は注意が必要です。