AS3中消除URLRequest加载外部循环音频延迟的方法求助
AS3外部加载音频循环首尾停顿问题的原因与解决
问题背景
已实现外部音频的基础无限循环逻辑:
var mysong:Sound = new Sound(new URLRequest("music/mysong.mp3")); mysong.play(0, int.MAX_VALUE);
但外部加载时循环首尾会出现轻微停顿,将音频放入项目库中则无此问题(已排除音频文件本身的问题)。经验证,循环过程中不会重新加载文件,但停顿问题仍存在。当前临时方案是在音频结束前50毫秒手动触发播放:
var music:SoundChannel = new SoundChannel(); music = mysong.play();
在帧进入事件监听器中执行:
if (music.position==6789) { music = mysong.play(); }
但该方案实用性差,固定提前量在不同设备上的准确性无法保证。
原因分析
- 解码机制差异:库内音频会在编译阶段完成预解码并缓存到内存,而外部加载的音频每次循环衔接时,AS3需要临时解码音频起始片段,产生短暂延迟。
- 缓冲区衔接间隙:外部加载的音频依赖运行时缓冲区,循环切换时缓冲区的衔接存在微小间隙,导致听觉上的停顿,而库内音频的缓冲区是预分配好的,衔接更流畅。
解决方法
方法1:基于SoundChannel事件的无缝衔接
利用音频时长和播放位置监听,在音频接近结束时提前启动新播放,通过精确的时间计算消除间隙:
var mysong:Sound = new Sound(new URLRequest("music/mysong.mp3")); var currentChannel:SoundChannel; var audioTotalLength:Number; // 加载完成后获取音频总时长 mysong.addEventListener(Event.COMPLETE, onSoundLoadFinish); function onSoundLoadFinish(e:Event):void { audioTotalLength = mysong.length; initLoop(); } function initLoop():void { currentChannel = mysong.play(); currentChannel.addEventListener(Event.ENTER_FRAME, checkLoopPoint); } function checkLoopPoint(e:Event):void { // 提前15ms启动新播放,可根据实际设备调整数值 if (currentChannel.position >= audioTotalLength - 15) { // 从剩余时长位置启动新播放,实现无缝衔接 currentChannel = mysong.play(audioTotalLength - currentChannel.position); e.currentTarget.removeEventListener(Event.ENTER_FRAME, checkLoopPoint); initLoop(); } }
方法2:缓存音频字节流模拟库内加载
将外部音频加载为ByteArray后重新初始化Sound对象,让音频处于预解码状态,接近库内音频的播放效果:
var soundCache:ByteArray; var mysong:Sound; var soundLoader:Loader = new Loader(); soundLoader.load(new URLRequest("music/mysong.mp3")); soundLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSoundLoaded); function onSoundLoaded(e:Event):void { soundCache = e.target.bytes; mysong = new Sound(); mysong.loadCompressedDataFromByteArray(soundCache, soundCache.length); mysong.addEventListener(Event.COMPLETE, onSoundReady); } function onSoundReady(e:Event):void { // 此时循环播放的效果与库内音频一致 mysong.play(0, int.MAX_VALUE); }
方法3:音频文件预处理(可选)
如果允许修改音频源文件,可使用Audacity等工具对音频首尾做10-20ms的淡入淡出处理,或者微调音频的起始/结束帧,让衔接处的过渡更自然,掩盖轻微停顿。
内容的提问来源于stack exchange,提问作者Koden
相关产品推荐
相关产品推荐

