AS3播放Mp3很简单,写两句sound = new Sound(request)然后监听Event.COMPLETE事件就可以开始播放了。播放中的进度和声道由SoundChannal对象负责,不过今天我遇到了一个小问题,关于SoundChannal的soundComplete事件,在播放暂停的时候,再继续播放,就无法监听播放完成这个事件。后来再仔细研究了一下,找到并解决了问题。
首先,帮助手册中写Event.soundComplete是由SoundChannal对象发出的,这个没错,不过它有一点没写清楚,就是每次调用Sound.Play()后返回的SoundChannal对象并不是原来的对象。为了把问题说清楚,我简单写一下流程。
首先是声明变量: var sound:Sound; var channal:SoundChannal;
第1步. 加载一个新声音: sound = new Sound(urlrequest)
第2步. 监听这个声音加载过程,有“OPEN”“PROGRESS”“COMPLETE”或者“IO_ERROR”这样的事件发生。
第3步. 加载了一定的数据后,可以开始播放: channal = sound.play(); 这个时候,声音播放的通道传递给了channal。
第4步. 监听音乐什么时候完成 channal.addEventListener(Event.SOUND_COMPLETE,play_is_complete);
第5步. 用户按了暂停按钮,把音乐暂停下来。SoundChannal和Sound都没有提供pause方法。压根就没有暂停方法,只能用 channal.stop();
第6步. 继续播放音乐,channal有stop却没有play方法,play方法在Sound对象里面,也就是说,我们只能停止,然后设定新的播放位置,让sound从这里开始重新播放。于是第6步就是不得不再写一次 channal = sound.play(postion); 但是这个时候出来的channal已经与第3步的channal不一样了,返回了一个新的SoundChannal对象。我们在第4步监听的事件是在旧的channal上,而现在新的并没有监听,表面上看起来像是失效了。结果就是音乐播放完成的时候,无法捕捉到soundComplete事件。
第7步. 正确的做法是,我们要还要再为第6步的新channal添加一个监听channal.addEventListener(Event.SOUND_COMPLETE,play_is_complete); 与第4步一样。
把第7步也补上,至此,问题解决。
刚开始做AS3的声音播放肯定会忽略第7步,这就是“播放声音暂停后为什么会无法监听到播放完成事件”的原因。这个问题花费了我30多分钟去调试。最后才发现问题是由一个小小的细节造成的:Sound.play()返回了新的SoundChannal,已经不是原来的那个了。搞程序确实比较费力,时间常常被耗在一些不起眼的小细节,很微小却又能让你的作品罢工。也许其他人已经写过了,就当是给自己是留个提醒备忘吧。
