大家期待以久的 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 );
}
}
}
留言