
ファイルをローカルにダウンロードさせるコンテンツを作る時、一般的にAS2までならgetURL、AS3ならnavigateToURLでそのファイルに直接リンクさせるのですが、問題点はブラウザによってはウィンドウが一瞬無駄に開いたり、(MP3ファイルなど)関連付けの設定によっては再生が始まったりしまうことがあります。(最悪なんか余計なソフトが立ち上がるとか)
Flash Player 8以降で使える、flash.net.FileReferenceクラスのdownload()メソッドを使うと、引数に指定したURL(AS1/2)、またはURLRequest(AS3)のファイルを、ダウンロードさせることが出来ます。
というわけで簡単なダウンロードUIを作ってみました。僕が昔宅録で作った曲(MP3)がダウンロードできます。(7.7MB)
流れとしては、FileReferenceインスタンスを作る→OPENなイベントを監視→OPENイベントからダウンロードの進捗を監視→ダウンロード完了後THANK YOUメッセージ表示、という感じです。
以下、AS2と、AS3の場合の実装コード例。
Action Script 2.0
ちなみに、セキュリティ上、ローカルでテストはできないです。Flash Playerのバージョンにもよるかもしれませんが、一度ウェブサーバーにアップして、httpプロトコルなサンドボックス上でしか動きません。
import flash.net.FileReference; //Flash 8からのクラスなので、インポート。
var _this:Object = this; //スコープ対策
var fr_listener:Object = new Object();
fr_listener.onOpen = function(fr:FileReference):Void
{
trace("start downloading");
}
fr_listener.onProgress = function(fr:FileReference, bytesLoaded:Number, bytesTotal:Number):Void
{
var percent:Number = Math.floor(bytesLoaded / bytesTotal * 100);
trace("downloading... " + percent + "%");
}
fr_listener.onComplete = function(fr:FileReference):Void
{
trace("thank you for your downloading!");
}
//FileReference作成
var fr:FileReference = new FileReference();
fr.addListener(fr_listener);
//btnクリックでダウンロードのためのダイアログ表示。
btn.onRelease = function():Void
{
_this.fr.download("song.mp3", "My Song.mp3");
}
Action Script 3.0
こちらは上のダウンロードUI例のコード。おわかりだと思いますが、gotoAndPlay()とかDisplayObjectなプロパティを操作してるところはアニメーションをさせているところです。コード汚いですねーとか言わなくていいですよ。
bar.scaleX = 0;
btn.buttonMode = true;
btn.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
btn.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
btn.addEventListener(MouseEvent.CLICK, clickHandler);
//FileReferenceインスタンス生成
var fr:FileReference = new FileReference();
function mouseOverHandler(event:MouseEvent):void
{
var target:MovieClip = MovieClip(event.currentTarget);
switch(target.name)
{
case "cancel_btn":
cancelmc.gotoAndPlay("on");
break;
case "btn":
downloadmc.gotoAndPlay("on");
downloadmc.arrowmc.gotoAndStop(1);
break;
}
}
function mouseOutHandler(event:MouseEvent):void
{
var target:MovieClip = MovieClip(event.currentTarget);
switch(target.name)
{
case "cancel_btn":
cancelmc.gotoAndPlay("off");
break;
case "btn":
downloadmc.gotoAndPlay("off");
downloadmc.arrowmc.play();
break;
}
}
function clickHandler(event:MouseEvent):void
{
var target:MovieClip = MovieClip(event.currentTarget);
switch(target.name)
{
case "cancel_btn":
fr.cancel();
destroy();
break;
case "btn":
start();
break;
}
}
function start():void
{
fr.download(new URLRequest("http://meditation-records.com/music/oriental.mp3"), "Oriental Colors.mp3");
fr.addEventListener(Event.OPEN, openHandler);
}
function openHandler(e:Event):void
{
fr.removeEventListener(Event.OPEN, openHandler);
btn.buttonMode = false;
btn.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
btn.removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
btn.removeEventListener(MouseEvent.CLICK, clickHandler);
fr.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
fr.addEventListener(Event.COMPLETE, loadCompleteHandler);
barbgmc.gotoAndPlay("show");
cancelmc.gotoAndPlay("show");
cancel_btn.visible = true;
cancel_btn.buttonMode = true;
cancel_btn.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
cancel_btn.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
cancel_btn.addEventListener(MouseEvent.CLICK, clickHandler);
}
function destroy():void
{
fr.removeEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
fr.removeEventListener(Event.COMPLETE, loadCompleteHandler);
barbgmc.gotoAndStop(1);
cancelmc.gotoAndStop("hide");
cancel_btn.visible = false;
cancel_btn.buttonMode = false;
cancel_btn.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
cancel_btn.removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
cancel_btn.removeEventListener(MouseEvent.CLICK, clickHandler);
bar.scaleX = 0;
percent_tf.text = "";
btn.buttonMode = true;
btn.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
btn.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
btn.addEventListener(MouseEvent.CLICK, clickHandler);
}
function loadProgressHandler(event:ProgressEvent):void
{
var per:Number = Math.floor(event.bytesLoaded / event.bytesTotal * 100);
percent_tf.text = per.toString() + "%";
bar.scaleX = per/100;
}
function loadCompleteHandler(event:Event):void
{
percent_tf.text = "100%";
bar.scaleX = 1;
thankyoumc.gotoAndPlay("show");
destroy();
}
という感じです。ちなみにhttpStatusとかもイベントで監視しておくと、よりカシコイと思われます。今回はめんどくさかったのでやりませんでした。
参考
Action Script 2.0用Adobe公式解説ページ
Action Script 3.0用Adobe公式解説ページ

