— boreal-kiss.com

Archive
2008年5月 Monthly archive

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

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

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

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

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

-debug=false -optimize=true

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

Read More

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();
}
Read More

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.

Read More

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

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用にビルドされているはずなんだけど何でかな。

Read More

[追記: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を参照ください。

Read More

久々に更新。どちらもテクノというよりは生音に近いので電子音苦手な人も聴けると思う。

»»» borealkiss.muxtape.com

Read More

追記 2008/12/01

この記事は2008年5月現在のものです。今どうなのか全然しりません!!!
************************

開発者ブログを読むかぎり現段階でサポートしていない(Pixel Bender Toolkitはサポートしている)。理由は動作確認の問題とかPlayerサイズをでかくしたくないとか色々書いてある。詳細はリンク先を読んでみてください。とりあえずwmode=”gpu”と書くだけ無駄なことがわかった。

You heard right, software run time. Pixel Bender kernels do not run using any GPU functionality whatsoever in Flash Player 10.

Take a breath. :-)
kaourantin.net: Adobe Pixel Bender in Flash Player 10 Beta

Read More
  1. あると便利なのでPixel Bender Toolkitをダウンロード。専用のpbkファイルがあれば実際のエフェクトの動作を手元で確認できる(もちろん元ソースも見れる)。
  2. Pixel Bender Exchangeより好みのフィルターをダウンロード。ここではTwirl Filterを使って説明(twirl.pbk)
  3. Pixel Bender ToolkitのFile > Open Pixel Bender Kernel Filter > twirl.pbkを選択
  4. File > Load Image > 好みの画像選択
  5. これで準備完了。あとはRunボタンを押せば画像にフィルターエフェクトが入り、フィルターのプロパティをスライダーを使ってリアルタイムに変更して見ることができる。twirlフィルターの場合、center(x,y)でエフェクトの中心位置、radiusでエフェクト範囲、twirlAngleでエフェクトの度合いを決定していることがわかると思う。
  6. File > Export Pixel Bender Byte Code Filter for FlashでFLASH読み込み用にパブリッシュ > twirl.pbj作成(すでにpbjファイルを同包したものもあるしpbjファイルしか配布していないものもある)

Flashに読み込ませるのは画像の扱いなんかと同じ。外部ファイルとして読み込ませる場合は以下の通り。例ではフィルターをかけるBitmapクラスは空なので適宜画像等を読み込ませてください。

import flash.display.Shader;
import flash.display.Bitmap;
import flash.events.Event;
import flash.filters.ShaderFilter;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;

var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.load(new URLRequest("twirl.pbj"));
loader.addEventListener(Event.COMPLETE,onComplete);

function onComplete(e:Event):void{  
    var img:Bitmap = new Bitmap();  
    var shader:Shader = new Shader(e.target.data);  
    var filter:ShaderFilter = new ShaderFilter(shader);   
    img.filters = [filter];
    addChild(img);
}

swfファイルに埋め込む場合は以下の通り。バイナリーデータとして埋め込むのでMime-typeの設定が必要(ここでもBitmapクラスは空)。

[Embed(source="twirl.pbj", mimeType="application/octet-stream")]
private var PbjObject:Class;

var img:Bitmap = new Bitmap();    
var shader:Shader = new Shader(new PbjObject());
var filter:ShaderFilter = new ShaderFilter(shader);
img.filters = [filter];

この時点でフィルターのプロパティについては何も設定していないのでエフェクトは表示されない。先ほどのtwirl.pbkのソースをPixel Bender Toolkitで見てみるとcenter, radius, twirlAngleについて以下のように記述されていることがわかる。

parameter float2 center
    <
        minValue:float2(0.0, 0.0);
        maxValue:float2(2048.0, 2048.0);
        defaultValue:float2(256.0, 256.0);
    >;

parameter float radius 
    <       
        minValue:float(0.1);
        maxValue:float(2048.0); 
        defaultValue:float(10.0);
    >;

parameter float twirlAngle
    <
        minValue:float(0.0);
        maxValue:float(360.0);
        defaultValue:float(90.0);
    >;

これらのプロパティへのアクセスは、例えばcenterのminValue, maxValue, defaultValueの場合はこんなかんじ。

//shader.data.center.minValueでもok
trace(shader.data["center"]["minValue"]);//0,0
trace(shader.data["center"]["maxValue"]);//2048,2048
trace(shader.data["center"]["defaultValue"]);//256,256

centerに値を入れたい場合はこんなかんじ。

//shader.data.center.valueでもok
shader.data["center"]["value"] = [125,125];
trace(shader.data["center"]["value"]);//125,125

shader.data["center"]["value"] = shader.data["center"]["defaultValue"];
trace(shader.data["center"]["value"]);//256,256

以下の例ではcenter=(125,125), radius=80, twirlAngle=100のエフェクトが画像に加えられる。

//shaderにはtwirl.pbj、imgには画像が格納済み
shader.data["center"]["value"] = [125,125];
shader.data["radius"]["value"] = [80];
shader.data["twirlAngle"]["value"] = [100];
filter= new ShaderFilter(shader);
img.filters = [filter];

完全なソースの例を見たい場合は以下のsourceを参照してください。
[FlashPlayer10]Twitter twirls
[FlashPlayer10]Twitter twirls

Read More

出たっぽい(英語)。ダウンロードはこちら

Thanks for informing, The Flash Blog!!

Read More

フィルターデータはAdobe – Pixel Bender Filtersを利用(Crystallize.pbj)。ギャラリーには他にも面白そうなものがいくつかあったので遊べそう。ところでadobeで配布されている個人制作フィルターなんだけど、何でフィルタープロパティに関して説明がないんだろう。今回はフィルターデータの内部をfor文で走査してプロパティを見つけた。他に便利な方法がないようであれば次回にでも書きます。あと、よく見たらビキニじゃなかった。

[関連リンク]
The Back Button » Working with Shaders/Filters in Flash 10
The Flash Blog » Loading Pixel Bender Filters in Flash 10
AstroのShaderFilter
AIF Toolkitメモ

[FlashPlayer10]Bikini de Mosaic
[FlashPlayer10]Bikini de Mosaic (要Flash Plaeyer 10)

ソース。たぶんPixel Bender Filterを利用するのに必要な最小限の内容しかないのでテンプレートみたいに使えると思う(もちろんフィルターのプロパティは変わる)。スライダーに関しては本質的ではないので割愛してます。

package {
    /*
    * Requires Flex SDK 3.0.1 or later to be compiled.
    */
    import flash.display.Bitmap;
    import flash.display.Shader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.filters.ShaderFilter;

    [SWF(width="550",height="400",backgroundColor="0x0",frameRate="24")]
    
    public class PixelBender03 extends Sprite{
        
        [Embed(source="data/250.jpg")]
        private var TestImage:Class;
        
        //Set mime-type as "binary", 
        //because the pbj object is in the binary form.
        [Embed(source="data/Crystallize.pbj", 
                mimeType="application/octet-stream")]
        private var PbjObject:Class;
        
        private var img:Bitmap;
        private var shader:Shader;
        private var filter:ShaderFilter;
        private var slider:SimpleSlider;
        
        public function PixelBender03(){
            //Photo
            img = new TestImage();
            img.x = stage.stageWidth/2 - img.width/2;
            img.y = stage.stageHeight/2 - img.height/2;
            addChild(img);
            
            //Pixel Bender filter
            shader = new Shader(new PbjObject());
            filter= new ShaderFilter(shader);
            var minValue:Number = shader.data.size["minValue"];
            var maxValue:Number = shader.data.size["maxValue"];
            var defaultValue:Number = shader.data.size["defaultValue"];
            shader.data.size.value = [defaultValue];
            img.filters = [filter];
            
            //Slider has a value between the 1st (min) and 2nd-argument (max), 
            //and the default value is defined by the 3rd-argument.
            slider = new SimpleSlider(minValue,maxValue,defaultValue);
            slider.x = 100;
            slider.y = stage.stageHeight/2 - slider.height/2;
            addChild(slider);
            slider.addEventListener(Event.CHANGE,onChange);
        }
        
        private function onChange(e:Event):void{
            shader.data.size["value"] = [slider.value];
            img.filters = [filter];
        }
    }
}
Read More