Adobe AIR 2.0 airhttpd でサーバ側でロードした swf のフレームショットをHTML5対応ブラウザで簡易アニメ表示させてみた
なんか airhttpd を使って面白いものを作れないかと思い、SWFLoader を使って外部 swf ファイルをロードし、そのフレームのスナップショットをHTTPクライアントに返すサーバーアプリを思いついた。
HTML 5 の Canvas 対応をブラウザであればそれを JavaScript で描画していくことができる。
開発環境とライブラリ
- Flex 3.5
- Adobe AIR 2.0 β2
- airhttpd - http://code.google.com/p/airhttpd/
ファイル構成
lib/ airhttpd-0.5.swc src/ docroot/ index.html webapp/ CGIService.as Main.mxml
CGI処理
airhttpd の FileService クラスを継承して CGIService クラスを作ります。
package webapp { import com.tilfin.airthttpd.server.HttpRequest; import com.tilfin.airthttpd.server.HttpResponse; import com.tilfin.airthttpd.services.FileService; import flash.filesystem.File; public class CGIService extends FileService { private var _snapShotFunc:Function; public function CGIService(snapShotFunc:Function, docroot:File) { super(docroot); _snapShotFunc = snapShotFunc; } override public function doService(request:HttpRequest, response:HttpResponse):void { if (request.path == "/action") { response.contentType = "image/png"; response.body = _snapShotFunc(); return; } super.doService(request, response); } } }
/action のリクエストが来たらコンストラクタで指定された snapShotFunc を呼び出して png の画像バイト配列を返す。
Main.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> <mx:Script> <![CDATA[ import com.tilfin.airthttpd.server.HttpListener; import webapp.CGIService; import mx.graphics.codec.PNGEncoder; private var _pngEncoder:PNGEncoder; private var _listener:HttpListener; public function init():void { _pngEncoder = new PNGEncoder(); _listener = new HttpListener(function(line:String):void { trace(line) }); _listener.service = new CGIService(getSnapShot, new File(File.applicationDirectory.nativePath + "/docroot")); _listener.listen(9080); } private function getSnapShot():ByteArray { var bmpdat:BitmapData = new BitmapData(150, 200, false); bmpdat.draw(loader.content); return _pngEncoder.encode(bmpdat); } ]]> </mx:Script> <mx:SWFLoader id="loader" width="150" height="200" opaqueBackground="0xffffff" cacheAsBitmap="true" source="SWFファイルのURL"/> </mx:WindowedApplication>
SWFLoader を一つ配置して、そのスクリーンショットを撮る getSnapShot を用意する。そのメソッドを CGIService に渡して HttpListener のサービスとしてセットする。
creationCompleteで以上を行い、サーバーを起動する。
index.html
ブラウザで表示する HTML 5 の HTMLファイル。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> var canvasContext; var imageCache; function init(){ imageCache = document.getElementById('image'); imageCache.onload = image_onload; canvasContext = document.getElementById('canvas').getContext('2d'); setInterval(timer, 200); } function timer(){ imageCache.src = "/action?dm=" + new Date().getTime(); } function image_onload(evt){ canvasContext.drawImage(imageCache, 0, 0); } </script> <title>Flash Viewer</title> </head> <body onload="init()"> <canvas id="canvas" width="150" height="200"></canvas> <img id="image" width="150" height="200" style="display:none"/> </body> </html>
timerで0.2秒おきにサーバーへ画像(スクリーンショット)を取得しに行く。いったん非表示のimageにロードし、ロード完了イベントで canvas のコンテキストに対して描画する(drawImage) 。
結果
こんな感じ iPod touch の Safari で http://AIRのサーバホスト:9080/ にアクセスするとパラパラ漫画のように Flash のアニメーションが表示される。
テストに使わせてもらった Flash は Afternoon Tea|Blog Parts|アフタヌーンティーの季節のテーマをモチーフにしたブログパーツ(無料)