Table of Contents
いくつか気になった点をテストプログラムで調べてみた。
Q.Soundのplayを何回も呼ぶとどうなるか。
A.同時に複数のSoundChannelが作られ、同時に再生される(音が重なる)。
Q.SOUND_COMPLETEはstopでも発生するのか。
A.発生しない。リファレンスには「サウンドの再生が終了したときに送出されます」とだけ書かれていたことによる疑問。
Q.ストリーム再生はどのような条件で行われるのか。
A.基本的に長い音ならばダウンロードが完了する前にplay()すれば常に行われると考えて良いみたい。ローカルからの再生は読み込みが速すぎてよく分からない。ローカルからの再生でもPROGRESSイベントは多数起きることだけは分かる。
Q.ストリーム再生はstop()だけでは止められないのか(明示的なcloseが必要なのか)。
A.開発ガイドには次のように書かれている。
ActionScript 3.0 のプログラミング / サウンドの操作 / サウンドの再生
サウンドのストリーミングの停止
ストリーミングしているサウンド、つまり再生中もロードを行うサウンドの再生には特異な処理があります。ストリーミングサウンドを再生している SoundChannel インスタンスの SoundChannel.stop() メソッドをアプリケーションで呼び出すと、1 つのフレームのサウンドの再生が停止し、次のフレームのサウンドの先頭から再生が再開されます。これは、サウンドのロード処理が実行中になっているためです。ストリーミングサウンドのロードと再生の両方を停止するには、Sound.close() メソッドを呼び出します。
↑の意味がよく分からないことによる疑問。stopすればちゃんと再生は止まる。再開されるようなことはないよ? 次のフレームってどういう意味だろう。もちろんcloseしなければロードは最後まで進行する。
Q.ストリーム再生中にstopせずにcloseするとどうなるのか。
A.読み込みが終わったところまで再生される。SOUND_COMPLETEイベントは発生しない。
テストに使ったコード
//Test.as package{ import flash.display.*; import flash.text.*; import flash.media.*; import flash.events.*; import flash.net.URLRequest; public class Test extends Sprite { private var tf:TextField = new TextField; private var snd:Sound = new Sound(); private var channel:SoundChannel; private var tfPrevLength:int = -1; private var tfCurrLength:int = -1; public function Test() { addButton("[STOP]", onClickStop, 0, 0); addButton("[CLOSE]", onClickClose, 100, 0); tf.text = ""; tf.autoSize = TextFieldAutoSize.LEFT; tf.y = 16; addChild(tf); snd.addEventListener(ProgressEvent.PROGRESS, onLoadProgress); snd.addEventListener(Event.COMPLETE, onLoadComplete); snd.addEventListener(IOErrorEvent.IO_ERROR, onIOError); snd.load(new URLRequest("test.mp3")); //読み込みが終わるまでにボタンが押せるくらい大きなmp3ファイル。 channel = snd.play(); channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); } private function addButton(text:String, func:Function, x:int, y:int):void { var t:TextField = new TextField(); t.text = text; t.x = x; t.y = y; t.autoSize = TextFieldAutoSize.LEFT; addChild(t); t.addEventListener(MouseEvent.CLICK, func); } private function onClickStop(e:MouseEvent):void { tf.appendText("channel.stopn"); channel.stop(); } private function onClickClose(e:MouseEvent):void { tf.appendText("snd.closen"); snd.close(); } private function onLoadProgress(e:ProgressEvent):void { // Progressイベントは全部表示すると鬱陶しいので、出来るだけまとめる。 if(tfCurrLength == tf.text.length){ tf.text = tf.text.substr(0, tfPrevLength); } tfPrevLength = tf.text.length; tf.appendText("LoadProgress " + e.bytesLoaded + "/" + e.bytesTotal + "n"); tfCurrLength = tf.text.length; } private function onLoadComplete(e:Event):void { tf.appendText("LoadCompleten"); } private function onSoundComplete(e:Event):void { tf.appendText("SoundCompleten"); } private function onIOError(e:IOErrorEvent):void { tf.appendText("IOError " + e.text); } } }