投稿日:2009-07-22 Wed
Pです。フルFlashサイトなどでよくある「BGMをずっとループ再生し続ける」時にハマッたのでメモ。
今回は、ただ鳴らすだけではなく再生プレイヤーのような一時停止→再開という機能もあります。
さて、音楽が再生されているときに一時停止するメソッドはあるけど、停止した位置から「再生しろ」というメソッドは残念ながらありません。なので自作する必要があるわけですが、これは簡単。
SoundChannel.positionを一旦変数に入れて保持しておき、Sound.play(stopPostion, 999)とすればOK。
これで一時停止からの再開は実装できたわけですが、これには大きな問題があります。
途中から再生したSoundをループさせると先頭に戻らずにループします。
例えばSound.play(5000, 999)とすると5秒目から再生されて最後までいったらまた5秒目から再生されます。う~ん、使い辛い……
と言うわけで私が取った方法は
ループ回数は常に1回で再生→Soundの終了をイベントで取得→また先頭から再生
です。
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextField;
public class SoundLoop extends MovieClip
{
private var bgm:Sound;
private var soundChannel:SoundChannel;
private var isBgm:Boolean = true;
private var stopPosition:Number = 0;
public function SoundLoop()
{
bgm = new Bgm();
bgmOnOff();
button.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void
{
isBgm = !isBgm;
bgmOnOff();
}
private function bgmOnOff():void
{
if (isBgm)
{
infoTxt.text = "再生中";
soundChannel = bgm.play(stopPosition, -1);
soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundEnd);
}
else
{
infoTxt.text = "停止中";
stopPosition = soundChannel.position;
trace(stopPosition);
soundChannel.stop ();
soundChannel.removeEventListener (Event.SOUND_COMPLETE, onSoundEnd);
}
}
//Soundの再生終了時
private function onSoundEnd(e:Event):void
{
soundChannel.removeEventListener (Event.SOUND_COMPLETE, onSoundEnd);
stopPosition = 0;
bgmOnOff();
}
}
}
今回のポイントは以下の2つ。
1.Sound.play(startTime:Number = 0, loops:int = 0)
2.SoundChannel.position
どちらとも私としてはどうも腑に落ちない点があります。
まずSound.play()の第二引数「loops」ですが、初期値0はループしません。1回鳴って終了。要するに値が1の時と全く同じ挙動なワケです。
それだったら初期値を1にして、0にすると無限ループだと分かりやすいのに!
単純にループ再生しようとしたらloopsに999とか大きい数を指定することになります。
次にSoundChannel.positionですが、Sound.play()の第二引数にループを指定している場合、通算再生時間で返ってきます。10秒(10000ミリ秒)の音楽をループ再生したとして3回目の途中でSoundChannel.positionを取ると25000などとなってしまうのです。これも注意。
△ PAGE UP