[as3]播放声音
播放一个加载的声音可以简单的调用Sound对象的Sound.play()方法,就像下面这样:
- var snd:Sound = new Sound(new URLRequest("smallSound.mp3"));
- snd.play();
当使用ActionScript3.0播放声音的时候,你可以实现下列操作:
- 从一个指定的位置播放声音(不一定是最开始)
- 暂停声音,然后从暂停的位置处重新开始播放
- 可以精确的知道声音什么时候播放完了
- 跟踪声音的播放进度
- 当声音播放的时候改变音量或者均衡
要在播放过程中实现这些效果,使用SoundChannel, SoundMixer, 和 SoundTransform 类.
SoundChannel控制一个单独的声音的播放.SoundChannel.position属性可以被当作播放头,用来指示数据播放的位置.
当程序调用Sound.play()方法时,会创建一个新的SoundChannel实例来控制播放.
程序可以为Sound.play()方法指定它的startTime参数,该参数接收以毫秒为单位的数字,这样就可以使声音从指定的位置开始播放.
如果同时指定了Sound.play()方法的startTime参数和loops参数,那么当声音会从相同的起始位置重复播放就像下面这样:
- var snd:Sound = new Sound(new URLRequest("repeatingSound.mp3"));
- snd.play(1000, 3);
在这个例子中,声音会接连从离开始1秒的位置播放3次.
暂停和重新开始声音
如果你的程序播放一个长声音,比如一首歌或者播客(podcasts,暂译为播客),你可能想允许用户可以暂停,然后继续播放这个声音.然后声音并不能像字面意思那样实现暂停,它只能停止(从字面意思上来讲,暂停跟停止是不同的,我们想实现暂停效果,但是没有直接的ActionScript语句可以实现暂停).但是,声音可以从任何位置处播放.因此你可以记录下它停止的位置,然后从这个位置后面开始播放,就实现了暂停效果.
比如,首先像下面这样加载并播放一个声音:
- var snd:Sound = new Sound(new URLRequest("bigSound.mp3"));
- var channel:SoundChannel = snd.play();
当声音播放的时候SoundChannel.position属性显示声音当前的播放位置.程序可以像下面这个例子一样,在停止它之前记录下它的位置:
- var pausePosition:int = channel.position;
- channel.stop();
要重新播放声音,传递之前记录的播放位置数据来使声音从它停止的地方重新开始播放.
- channel = snd.play(pausePosition);
监视播放
你的程序可能需要知道什么时候它停止了播放,以便去播放另一个声音,或者清除在播放过程中使用的一些资源.当声音播放完毕的时候SoundChannel类发送一个Event.SOUND_COMPLETE事件. 你的程序可以监听这个事件并作出适当的动作,就像下面这样:
- import flash.events.Event;
- import flash.media.Sound;
- import flash.net.URLRequest;
- var snd:Sound = new Sound("smallSound.mp3");
- var channel:SoundChannel = snd.play();
- s.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
- public function onPlaybackComplete(event:Event)
- {
- trace("The sound has finished playing.");
- }
SoundChannel类在播放中并不发送进度事件.要报告播放进度,你可以自己设置一个时间进制并跟踪播放头的位置.
可以使用SoundChannel.position属性值除以声音长度来计算已播放的百分数:
- var playbackPercent:uint = 100 * (channel.position / snd.length);
但是,只有在播放前声音全部加载完了,这段代码才能精确显示播放的百分比.Sound.length属性显示的是当前已加载的声音长度,而不是声音文件的的真实长度.你可以使用Sound对象的bytesLoaded和bytesTotal属性估计声音的长度:
- var estimatedLength:int =
- Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
- var playbackPercent:uint = 100 * (channel.position / estimatedLength);
下面的代码加载一个比较大的声音文件,并使用Event.ENTER_FRAME事件作为显示播放进度的时间机制.它周期性的报告播放的百分比,这个百分比是用当前位置除以声音总长度计算出来的:
- import flash.events.Event;
- import flash.media.Sound;
- import flash.net.URLRequest;
- var snd:Sound = new Sound();
- var req:URLRequest = new
- URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3");
- snd.load(req);
- var channel:SoundChannel;
- channel = snd.play();
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
- snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
- function onEnterFrame(event:Event):void
- {
- var estimatedLength:int =
- Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
- var playbackPercent:uint =
- Math.round(100 * (channel.position / estimatedLength));
- trace("Sound playback is " + playbackPercent + "% complete.");
- }
- function onPlaybackComplete(event:Event)
- {
- trace("The sound has finished playing.");
- removeEventListener(Event.ENTER_FRAME, onEnterFrame);
- }
在开始加载声音数据后,调用方法snd.play()并把结果保存在类型为SoundChannel,名子为channel的变量中. 然后为主程序添加了Event.ENTER_FRAME事件的监听器,为SoundChannel对象的Event.SOUND_COMPLETE事件也添加了监听器.
在动画中每到达一个新帧的时候,onEnterFrame()方法就会被调用.onEnterFrame()根据已经加载的数据估算声音的总长度,然后显示当前播放的百分数.
当整个声音播放完后,会执行onPlaybackComplete()方法,移除Event.ENTER_FRAME事件的监听器,因为播放完后就不需要在报告播放进度了.
Event.ENTER_FRAME事件每秒会发送好几次.在某些情况下,你可能不想发送的这么频繁.那么,你就可以使用flash.util.Timer类设置自己的时间机制.
停止流声音
流声音(指的是在完全加载之前就播放的声音)在播放过程中有一个特点需要注意.当你的程序调用SoundChannel.stop()方法的时候,声音会停止一帧,而在下一帧它会从开始的地方重新开始播放. 之所以发生这种情况,是因为声音仍然在加载中.要停止加载和播放,使用Sound.close()方法.

6月 10th, 2007 at 8:04 下午
坏蛋!
6月 10th, 2007 at 8:06 下午
小屁孩!
6月 10th, 2007 at 8:30 下午
看你再拦我,就骂你!