Google SwiffyとCreateJSでAJAX通信入りFlash動画の変換に挑戦してみた

こんにちは!
13新卒エンジニアの古川です。今回が初めての投稿です!よろしくお願いします。

今回はAJAX通信入りFlash動画をJSに変換することが可能なのか、実際に検証した内容を記事にしました!


実際に試したツール

Google Swiffy
 Googleが提供しているFlash動画をSVGに変換してくれるサービスです。
   https://www.google.com/doubleclick/studio/swiffy/

・CreateJS
 Adobeが提供しているFlash Professional用のアドインで、Flash動画をHTML5CanvasJavascriptに変換してくれるツールです。
   http://www.createjs.com/


検証に使ったFlash動画

まず最初に、この画面が表示されます。
フラッシュ例その1


そのあと、Ajax通信で取得した値をもとに、次のように「晴れ!」か「雨...」を表示させます。Ajax通信で取得できる値は0~100のランダムな数字です。この値が0~50の場合は晴れを表示して、51以上は雨を出す感じですね。

0~50 の場合
フラッシュ例その2

50~100の場合 
フラッシュ例その3




なお、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>

これを実際に実行。
CreateJS結果(天気は?)

1回目

晴れ!
GoogleSwiffy結果(晴れ)

雨出るまで更新を繰り返す・・・

出た!!!
GoogleSwiffy結果(雨)


見事に動きました。

次にスマホ実機テスト。だがしかし、ここで思わぬ罠が・・・・

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でアニメーションを操作する。(ActionScriptJavascriptに変換してくれると思ったら大間違いだったのですね・・・

はじめての人は嵌るかもしれないので注意が必要。

というわけで、これにめげず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 雨を表示するシーン

あ、あとjQueryAjax使ってるので、それのロードも忘れないように!

パブリッシュし、開発サーバに放り込んでテストしてみました。

1回目

雨!
GoogleSwiffy結果(雨)

晴れが出るまで更新を繰り返す・・・

出た!!!
GoogleSwiffy結果(晴れ)



お~動いた!

あとは気になるAndroid2シリーズの対応はというと・・・こんな感じです。

Android2.1×
Android2.2○
Android2.3○


これなら問題なく使えるね!


結論

結果的にどちらのツールでも実現できましたが、今の現状、Android2.3のシェア率が高いので、通信処理を含むフラッシュ動画をJSに変換するツールはCreateJSが最適ということがわかりました。Android2.3はそのうちシェア率が減ってきますので、Android4が主流になったときはGoogle Swiffyもありです。

※CreateJSにはシーンがひとつしか使えないだけでなく様々な制約があるため、高度なエフェクトを使う場合は注意が必要です。