FileReference.loadを含むファイルをFlex Builderでコンパイルする時のチップ

Tags:

かなり限定的なシチュエーションだけど、Flex Buider 3のリリース用にコンパイルしたswfファイル内のFileReference.loadは

  • ネットワーク上で動作しない(IllegalOperationError #2014)
  • ローカルで動作する

デバッグ情報込みでコンパイルしたswfファイル(デフォルトだとbin-debug内に作成されるやつ)は

  • ネットワーク上で動作する
  • ローカルで動作する

FlexibleFactoryの方からも同様の旨のコメントをもらったのでおそらく間違った情報ではないはず。デバッグバージョンを使えばネットワーク上でも動作するから問題ないっちゃ問題ないんだけど、デバッグ情報が入ってる分ファイルサイズが結構大きくなるのが嫌。そこでプロジェクト > プロパティ > ActionScriptコンパイラ > 追加コンパイラ引数に以下を記述。

-debug=false -optimize=true

これでbin-debugに作成されるswfファイルがリリースビルドで作成されるswfファイルと同サイズになる。もちろんこのオプションだとデバッグはできないので、リリース用に書き出すギリギリに付け加えるのがいいかも。そもそも何でこんな状況になるのかは不明なので、何か情報をお持ちであればフィードバックもらえるとうれしいです。設定が面倒くさくてかないません。

FileReference.loadでサウンドをロードするライブラリ

Tags:

FileReference.loadは読み込んだデータがByteArray型になるため、ByteArrayを読み込むメソッドがないSoundクラスの場合かなり不便。FlexibleFactoryでFileReference.loadで選択したMP3ファイルを再生するパッケージが配布されている。使い方も超簡単。ローカルのMP3からサウンドスペクトラムを表示するサンプルを作ってみた。自分のチョイスした曲を無理矢理聴かせるよりは良心的かな。

[FlashPlayer10]Suck Your Music
(要Flash Player 10)

import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;
import org.audiofx.mp3.MP3FileReferenceLoader;
import org.audiofx.mp3.MP3SoundEvent;

_loader:MP3FileReferenceLoader = new MP3FileReferenceLoader();
_loader.addEventListener(MP3SoundEvent.COMPLETE,onComplete);
_fr:FileReference = new FileReference();
_fr.addEventListener(Event.SELECT,onSelect);
stage.addEventListener(MouseEvent.CLICK,onClick);

function onClick(e:MouseEvent):void{
    _fr.browse();
}

function onSelect(e:Event):void{
    _loader.getSound(_fr);
}

function onComplete(e:MP3SoundEvent):void{
    e.sound.play();
}

A question to FlexibleFactory about FileReference.load

Tags:

Since I could not place a comment on your site, http://www.flexiblefactory.co.uk/flexible/, unless I login your site, I am asking you here. I am happy if you would give me any suggestions;

I enjoyed your latest post, How to load MP3 files from a FileReference. However this did not work in the Internet (e.g., http://boreal-kiss.com/xxx.swf), while it does work locally (not a local site but a simple browsing test). When the swf file run in the network, the FileReference.load (or some similar method) gives an “IllegalOperationError #2014: Feature is not available at this time”. So the question is “did you verify whether your program work even in the Internet?”.

I am curious about that as I also failed to run a simple FileReference.load for loading image files in remote realm (that works locally).

PS., I found a problem that a SWF file release-built by Flex Builder 3 does not work while that debug-built by does, although both of which are compiled for Flash Player 10. I didn’t solve the detail, but I could upload SWFs working well on my website! Thanks a lot.

FileReference.loadがリモートサーバーで動作しない(半分解決済み)

Tags:

ローカルでは動作するのにサーバーにアップすると以下のエラーを吐く。

Error #2014 現在は使用できない機能です。このシステムではサポートされていない機能です。

何か設定が必要なのかな。誰かサーバーにアップして動作テストしておくれ。関係あるかしらんけどうちはさくらインターネット(月額500円)です。

//The swf file resides within a remote server, 
//ex., http://boreal-kiss.com/xxx.swf

var f:FileReference = new FileReference();

try{
    //Works well in the local, but…
    f.load();
}
catch(e:Error){
    //This is the result for my webserver.
    trace(e.message);//Error #2014
}

[追記:2008/05/28]

FileReference.loadがthrowしているのはIllegalOperationErrorだと判明。

IllegalOperationError 例外は、メソッドが実装されていないか、使用方法に実装が対応していない場合にスローされます。たとえば、次のような状況で無効な操作エラーの例外が発生します。

  • 基本クラス (DisplayObjectContainer など) に、ステージでサポートされている範囲を超えた機能 (マスクなど) がある場合。
  • アクセシビリティのサポートを含めずにコンパイルされた Flash Player の環境で、ある種のアクセシビリティ関連メソッドを呼び出した場合。
  • mms.cfg での設定により、FileReference アクションが禁止されている場合。
  • ActionScript が、参照ダイアログボックスが既に表示されているときに FileReference.browse() 呼び出しを実行しようとした場合。
  • ActionScript が、FileReference オブジェクトでサポートされていないプロトコル (FTP など) を使用しようとした場合。
  • ランタイムプレーヤーでオーサリング時専用の機能を呼び出した場合。
  • タイムライン上に配置されたオブジェクトに対して名前を設定しようとした場合。

ActionScript 3.0 コンポーネントリファレンスガイド

状況を考えるとFTPかmms.cfgが怪しいなあ。

[追記:2008/05/29]

とりあえず現時点まででわかっていること。

  • SecurityErrorではない
  • 同じ環境でFileReference.uploadは正常に動作する(i.e., IllegalOperationErrorを吐かない)

これは参った。FileReference.uploadがIllegalOperationErrorを吐く条件はFileReference.loadがそれを吐く条件を網羅している。mms.cfg(Macromedia Security Configuration file)がなくてもFileReference.uploadは機能しているのでmms.cfgは何らかの動作を明示的に禁止する際に作成するものなんだと思う(わざわざ作成しないと動作の許可ができないとそれこそ不便きわまりない)。そうするとFileReference.loadがリモートサーバーで機能しない理由の候補としては

  • 現段階で本当に機能していない(将来的に動作するようになる)
  • リモートサーバーで機能する仕様ではない(リファレンスにはユーザーのローカルファイル云々の言及はあるがファイルロード先について一言も説明がないので不明)

まさかローカルファイルをローカルswfのみにロードできる機能ってことはないよね?

[追記:2008/05/29]

Flex Builder 3のリリースビルド(bin-release内)したものでエラーが出ることがわかった。bin-debugにコンパイルされたものはネットワーク上でも動く。どちらもFlash Player 10用にビルドされているはずなんだけど何でかな。

FileReference.loadで画像を読み込むとイメージプロパティがわからず超不便(解決済み)

Tags:

[追記:2008/05/27]

解決しました。Loader.loadBytesのイベント取得前にプロパティにアクセスしようとしていたことが原因でした。記事最下部に新たに修正コードを載せておきます。

Flash Player 10から、FileReference.loadでローカルにあるファイルをFlash Playerにロードできるようになった。ただしFileReference.loadでロードしたデータは必ずバイナリ形式になるので、画像データを読み込ませたいときには一工夫必要。以下の例のようにLoader.loadBytesを使わなければいけない。([追記:2008/05/27]記事最下部に修正版があるのでそちらを参照ください)

import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;

var _fr:FileReference = new FileReference();
stage.addEventListener(MouseEvent.CLICK,onClick);
_fr.addEventListener(Event.SELECT,onSelect);
_fr.addEventListener(Event.COMPLETE,onComplete);

function onClick(e:Event):void{
    _fr.browse();
}

function onSelect(e:Event):void{
    var f:FileReference = FileReference(e.target);
    f.load();
}

function onComplete(e:Event):void{
    var f:FileReference = FileReference(e.target);
    var loader:Loader = new Loader();
    loader.loadBytes(f.data);
    addChild(loader);
}

ところで、Load.loadBytesで読み込むとLoaderは元画像のwidthなんかのプロパティ情報を保持しなくなる。上の例で画像を読み込ませてloaderの中身を見てみると以下のようになる。

trace(loader.content);//null
trace(loader.contentLoaderInfo);//[object LoaderInfo]
trace(loader.contentLoaderInfo.content);//null
trace(loader.contentLoaderInfo.content.width);//Error: no such properties!!

Loader.content、Loader.contentLoaderInfo.contentともに存在しない。”プロパティが存在しない”というこの性質を利用するとFlash Playerの制限を超えるサイズの画像もロードできるみたいだけど(void element blog: 2880pxよりも大きい画像を読み込む方法を発見したよ)、読み込んだ画像のサイズがわからんのでは扱いに困る。ユーザーの好きなサイズのファイルをローカルからロードできるところが面白いのに。どんな寸法の画像をロードされても例えばステージ中心に配置するにはどうすればいいのかね。

[追記:2008/05/27]

FileReference.loadで画像を読み込んでイメージプロパティを取得するまでの修正コード。

import flash.display.Loader;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;

var _fr:FileReference = new FileReference();
stage.addEventListener(MouseEvent.CLICK,onClick);
_fr.addEventListener(Event.SELECT,onSelect);
_fr.addEventListener(Event.COMPLETE,onComplete);

function onClick(e:Event):void{
    _fr.browse();
}

function onSelect(e:Event):void{
    var f:FileReference = FileReference(e.target);
    f.load();
}

function onComplete(e:Event):void{
    var f:FileReference = FileReference(e.target);
    var loader:Loader = new Loader();
    loader.loadBytes(f.data);

    //It’s too early!!
    //addChild(loader);
    loader.contentLoaderInfo.addEventListener(Event.INIT,init);
}

//Add the image at the stage center
function init(e:Event):void{
    trace(e.target.content);//[object Bitmap]
    var bmp:Bitmap = Bitmap(e.target.content);
    bmp.x = stage.stageWidth/2 - bmp.width/2;
    bmp.y = stage.stageHeight/2 - bmp.height/2;
    addChild(bmp);
}

追記 2008/10/19

Filereferenceオブジェクトの参照方法について補足。参照している変数が(全て)スコープ範囲外に移動すると、FileReference.load()などの一部のメソッドは途中キャンセルされる。詳しくはFileReferenceオブジェクトと変数のスコープの関係 - boreal-kiss.comを参照ください。

Next Page →