SoundChannelの最近のブログ記事

Soundクラスによるサウンド再生でシークバーをつけたんだけど、Sound,SoundChannelクラスにはseek()がない。基本的にはSound.play(time)で時間指定をすればいいのだけれど、再生停止中に

sndCh = Sound.play(n);
snfCh.stop();

とやっても、SoundChannel.positionの値が更新されない。なので、再生停止中は、volumeを0にした状態で最小時間(1ms)再生してからSoundChannel.stop()することで対応してみた。他にいいやり方あるのかしらん?

以下、シーク対応を含むクラスです。

package {
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;

import flash.events.EventDispatcher;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.events.Event;

import flash.net.URLRequest;

import flash.utils.Timer;
import flash.events.TimerEvent;

public class SoundLoader extends Loader {
var snd:Sound;
var sndCh:SoundChannel;
var sndTF:SoundTransform = new SoundTransform();
var sndVol:Number;

var flg_play:Boolean;
var flg_repaet:Boolean;

var isNowPlaying:Boolean;

var fn_sndComplete:Function;

var timer:Timer;
const time_interval:Number = 1;

function SoundLoader(url:String,isPlay:Boolean,
isRepeat:Boolean,fn:Function=null) {
flg_play = isPlay;
flg_repaet = isRepeat;
fn_sndComplete = fn;

//再生中フラグ:初期化
isNowPlaying = false;

//サウンド:ロード
snd = new Sound();

snd.addEventListener(Event.COMPLETE,loadCompleteHandler);
var urlReq:URLRequest = new URLRequest(url);
snd.load(urlReq);
}

//sound:ロード完了時の処理
function loadCompleteHandler(evt:Event):void {
if (flg_play) {
sndCh = snd.play(0);
sndCh.addEventListener(Event.SOUND_COMPLETE,
  soundCompleteHandler);

isNowPlaying = true;
}
}

//sound:再生終了時の処理
function soundCompleteHandler(evt:Event):void {
trace("再生終了!");
if (flg_repaet) {
//repeat:あり
sndCh = snd.play(0);
sndCh.addEventListener(Event.SOUND_COMPLETE,
  soundCompleteHandler);
} else {
//repeat:なし
isNowPlaying = false;

//再生後の処理が指定されている場合:実行
if (fn_sndComplete != null) {
fn_sndComplete();
}

}
}

//sound:再生
public function playSound():void {
var pausePosition:int;
if (sndCh == null) {
//初回再生の場合
pausePosition = 0;
} else if (sndCh.position == snd.length) {
//最後まで再生した場合
pausePosition = 0;
} else {
//それ以外
pausePosition = sndCh.position;
}
sndCh = snd.play(pausePosition);
sndCh.soundTransform = sndTF;

sndCh.addEventListener(Event.SOUND_COMPLETE,
  soundCompleteHandler);

isNowPlaying = true;
}

//sound:一時停止
public function stopSound():void {
sndCh.stop();
sndCh.removeEventListener(Event.SOUND_COMPLETE,
 soundCompleteHandler);

isNowPlaying = false;
}

//sound:巻き戻し
public function rewSound():void {
if (isNowPlaying) {
//再生中
sndCh.stop();
sndCh = snd.play(0);
sndCh.removeEventListener(Event.SOUND_COMPLETE,
 soundCompleteHandler);
} else {
//停止中
//sndCh.stop();
sndCh = snd.play(0);
sndCh.stop();
}
}

//sound:リピート切替
public function repeatSound(isRepeat:Boolean):void {
flg_repaet = isRepeat;
}

//sound:再生位置取得
public function getPosition():Number {
var pos_return:Number;
if (sndCh == null) {
//一度も再生していない場合
pos_return = 0;
} else {
//再生済みの場合
pos_return = sndCh.position;
}

return pos_return;
}

//sound:長さ取得
public function getLength():Number {
return snd.length;
}

//sound:再生位置合わせ
public function setPosition(position_sound:Number,
flg_play:Boolean):void {
//再生位置:指定
sndCh = snd.play(position_sound);

if (flg_play) {
//---再生
sndCh.addEventListener(Event.SOUND_COMPLETE,
  soundCompleteHandler);
isNowPlaying = true;
} else {
//---再生しない
//現在のボリューム:保存
sndVol = sndTF.volume;

//位置移動用にvolumeをゼロにする
var tf:SoundTransform = new SoundTransform(0);
sndCh.soundTransform = tf;

//サウンド位置合わせタイマー:起動
setIntervalTimer_sound();
}
}

//---------------------------------------------------
// sound.play()>SoundChannel.stop()を連続させても、
// SoundChannel.positionの値が変更されないので、
// 最小時間(1ms)だけ無音で再生してから停止する。
//---------------------------------------------------
//サウンド位置合わせタイマー:起動
function setIntervalTimer_sound():void {
timer = new Timer(time_interval,1);
timer.addEventListener(TimerEvent.TIMER, onStopSound_timer);
timer.start();
}


//サウンド位置合わせタイマー:サウンド停止
function onStopSound_timer(event:TimerEvent):void {
//再生停止
sndCh.stop();

//volume:元に戻す
var tf:SoundTransform = new SoundTransform(sndVol);
sndCh.soundTransform = tf;
}

}

}



AS3.0ではサウンド制御も変更されていて、基本的にSoundクラスとSoundChannelクラスを使う。例えば、外部mp3を再生する場合は。こんな感じ。

var sd_song:Sound;
var sd_channel:SoundChannel;

function xInitSound_song():void {
sd_song = new Sound();
var url:String = "mp3/" + "Pissism-Blade.mp3";
var urlReq:URLRequest = new URLRequest(url);

sd_song.addEventListener(Event.COMPLETE,onCompleteSound_load);
sd_song.load(urlReq);
}

function onCompleteSound_load(evt:Event):void {
trace("---ロード完了",evt.target);
}

function xStartSound_song(evt:MouseEvent):void {
sd_channel = sd_song.play();
}

xInitSound_song();
btn_play.addEventListener(MouseEvent.CLICK,xStartSound_song);

で、使用しているチャンネルの音量は、SoundChannel.soundTransform.volumeで制御することになるのだけれど、

function xVolume0_song(evt:MouseEvent):void {
var st:SoundTransform = sd_channel.soundTransform
st.volume = 0
sd_channel.soundTransform = st
}

と書いても、サウンド再生中は制御できる(volume=0になる)けど、停止しているときに0にしても再び再生するとvolumeは0にはならない。要はSoundChannelのsoundTransformは再生しているSoundクラスに対してのみ有効ということらしい。SoundChannelという器の設定ではないんですね。

コレだと全体の音量制御ができない。いろいろ検索してみたら、SoundMixer.soundTransformで制御すると、swf全体の制御が出来るらしい。

function xVolume0_song(evt:MouseEvent):void {
var st:SoundTransform = SoundMixer.soundTransform;
st.volume = 0;
SoundMixer.soundTransform = st;
}

SoundMixerクラスを使うことで、swf全体のサウンド制御ができ、かつサウンドの再生・停止に依存せずに音量制御ができる。

検索中に下記サイトでこの辺の制御をクラス化したものを発見。コレ、便利そう。


このアーカイブについて

このページには、過去に書かれたブログ記事のうちSoundChannelカテゴリに属しているものが含まれています。

前のカテゴリはSoundです。

次のカテゴリはTimerです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。