大家期待以久的 Flash 多執行序來了(還是只有我在期待)
在之前 Flash 只要有程式塞住, 就會整個像死檔一樣的掛掉
現在多了執行序的幫忙, 可以把較吃效能的動做交由背景來除理
這樣就不會影響本來的動畫
筆者寫的 Demo 就是用 Sound 類別的 extract, 把整首 mp3 轉成 ByteArray , 好來製作加速播放功能,之前在轉換的過程,會整個卡住
用了 Worker 多執行序就可決解這樣的問題
線上 Demo, 請確定你的 FlashPlayer 為 11.4 以上的版本才看的到
https://dl.dropbox.com/u/2069696/blog/index.html?s=2012_10_09_FP11_Worker/worker
轉載請註明出處
在之前 Flash 只要有程式塞住, 就會整個像死檔一樣的掛掉
現在多了執行序的幫忙, 可以把較吃效能的動做交由背景來除理
這樣就不會影響本來的動畫
筆者寫的 Demo 就是用 Sound 類別的 extract, 把整首 mp3 轉成 ByteArray , 好來製作加速播放功能,之前在轉換的過程,會整個卡住
用了 Worker 多執行序就可決解這樣的問題
線上 Demo, 請確定你的 FlashPlayer 為 11.4 以上的版本才看的到
https://dl.dropbox.com/u/2069696/blog/index.html?s=2012_10_09_FP11_Worker/worker
轉載請註明出處
/** * @author milkmidi */ package { import com.bit101.components.HUISlider; import com.bit101.components.PushButton; import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.events.SampleDataEvent; import flash.media.Sound; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; import flash.text.TextField; import flash.utils.ByteArray; import net.hires.debug.Stats; import swc.milkmidi.Intro_mc; public class LoadSoundExtract extends Sprite { static public const BYTES_PER_CALLBACK:int = 4096; private var samplesData:ByteArray; private var _phase:Number=0; private var playbackSpeed:Number = 1; private var numSamples:int; private var worker:Worker; private var mainToBack:MessageChannel; private var backToMain:MessageChannel; private var backWorker:ParseMP3Worker; private var _tf:TextField; public function LoadSoundExtract() { stage.scaleMode = "noScale"; stage.align = "tl"; addChild( new Stats).x = 535; addChild( _tf = new TextField); _tf.width = 400; var intro:DisplayObject = addChild( new Intro_mc ); intro.x = stage.stageWidth >> 1; intro.y = stage.stageHeight >> 1; var u:HUISlider = new HUISlider( this , 0, 20,"SPEED", function ():void { playbackSpeed = u.value; }); u.setSliderParams( -4 , 4, 1); new PushButton( this, 0,40,"LOAD",function ():void { mainToBack.send("load"); trace("[Main] load"); }); if (Worker.current.isPrimordial) { trace("primordial worker"); worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes); worker.addEventListener(Event.WORKER_STATE, workerEventListener); mainToBack = Worker.current.createMessageChannel(worker); backToMain = worker.createMessageChannel(Worker.current); worker.setSharedProperty("mainToWorker", mainToBack); worker.setSharedProperty("workerToMain", backToMain); backToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMainHandler); worker.start(); } else { backWorker = new ParseMP3Worker( ); } } private function onWorkerToMainHandler(e:Event):void { var msg:* = backToMain.receive(); if (msg is String) { trace("onWorkerToMainHandler:", msg); _tf.text = msg + ""; } switch (true) { case msg == "onSoundProgress": _tf.text = backToMain.receive() + "%"; break; case msg == "extractComplete": samplesData = backToMain.receive(); if (samplesData != null) { numSamples = backToMain.receive(); trace( 'numSamples:' + numSamples ); //samplesData.position = 0; var sampleSound:Sound = new Sound(); sampleSound.addEventListener(SampleDataEvent.SAMPLE_DATA , _onSampleDataHandler ); sampleSound.play(); } break; } } private function workerEventListener(e:Event):void { trace("worker state:" + e.target.state); } protected function _onSampleDataHandler(e:SampleDataEvent):void { var l :Number; var r :Number; var i:int = 0; while (i++ < BYTES_PER_CALLBACK ) { //pos = int(_position); samplesData.position = int(_phase) * 8; l = samplesData.readFloat(); r = samplesData.readFloat(); e.data.writeFloat(l); e.data.writeFloat(r); //上面四行可以換成下面一行。 //e.data.writeDouble(samplesData.readDouble()); _phase += playbackSpeed; if (_phase >= numSamples) { //outputSnd.close(); trace("loop"); _phase -= numSamples; } } } }//__________________________________________________________________________________ End Class }//__________________________________________________________________________________ End Package import flash.events.Event; import flash.events.ProgressEvent; import flash.media.Sound; import flash.net.URLRequest; import flash.system.MessageChannel; import flash.system.Worker; import flash.utils.ByteArray; class ParseMP3Worker { private var mainToWorker:MessageChannel; private var workerToMain:MessageChannel; private var sourceSnd:Sound; public function ParseMP3Worker( ) { super(); mainToWorker = Worker.current.getSharedProperty("mainToWorker"); workerToMain = Worker.current.getSharedProperty("workerToMain"); mainToWorker.addEventListener(Event.CHANNEL_MESSAGE, onMainToWorkHandler); sourceSnd = new Sound(); sourceSnd.addEventListener( ProgressEvent.PROGRESS, onSoundProgressHandler); sourceSnd.addEventListener(Event.COMPLETE, onSoundLoadedComplete); workerToMain.send( "ParseMP3WorkerConstructor"); } private function onSoundProgressHandler(e:ProgressEvent):void { var p:int = int(e.bytesLoaded / e.bytesTotal * 100); workerToMain.send( "onSoundProgress"); workerToMain.send( p ); } private function onSoundLoadedComplete(e:Event):void { workerToMain.send( "onSoundLoadedComplete"); var byte:ByteArray = new ByteArray(); var length:Number = sourceSnd.length * 44.1; sourceSnd.extract( byte , length ); workerToMain.send( "extractComplete"); workerToMain.send( byte ); workerToMain.send( length ); } private function onMainToWorkHandler(e:Event):void { var msg:* = mainToWorker.receive(); try { switch (true) { case msg == "HELLO": workerToMain.send("WORLD"); break; case msg == "load": sourceSnd.load( new URLRequest( "https://dl.dropbox.com/u/2069696/Doraemon.mp3" )); break; } }catch (err:Error){ workerToMain.send( err.message ); } } }
留言