AS3:如何结合Timer类实现声音平滑淡出至停止?
用Timer实现声音线性增减(半程平滑淡出停止)
原代码存在的问题
- Timer初始化时
count=1,导致计时器仅触发一次,无法实现持续的音量调整;且先启动Timer再播放声音,逻辑顺序错误。 _timer回调函数内直接移除事件监听并停止音频,触发一次就终止,完全没有平滑调整的机会。- 音量计算逻辑混乱,仅在
vol==1时调整一次音量,没有持续递减的逻辑。 - 未获取音频总时长,无法判断何时进入半程淡出阶段。
正确实现方案
核心思路:先获取音频总时长,计算半程时间点;用高频Timer(比如20ms间隔)持续检测播放进度,到达半程后逐步降低音量,直到音量为0时停止音频和Timer。
var _mysound: mysound = new mysound(); var mysoundchannel: SoundChannel; var soundtimer: Timer; // 存储当前音量,初始为1 var currentVol: Number = 1; // 淡出步长,越小越平滑,根据Timer间隔调整 var fadeStep: Number = 0.02; // 音频总时长(毫秒) var totalDuration: Number; // 半程淡出开始时间(毫秒) var fadeStartTime: Number; bt_.addEventListener(MouseEvent.CLICK, _click); function _click(event: MouseEvent): void { // 先获取音频总时长 totalDuration = _mysound.length; fadeStartTime = totalDuration / 2; // 初始化Timer,20ms触发一次,不限制次数 soundtimer = new Timer(20); soundtimer.addEventListener(TimerEvent.TIMER, onTimerTick); // 开始播放音频 mysoundchannel = _mysound.play(); // 启动Timer soundtimer.start(); } function onTimerTick(event: TimerEvent): void { // 获取当前播放时长 var currentPlayTime: Number = mysoundchannel.position; // 检查是否到达淡出开始时间 if (currentPlayTime >= fadeStartTime) { // 线性降低音量 currentVol -= fadeStep; // 确保音量不低于0 currentVol = Math.max(currentVol, 0); // 更新音频音量 mysoundchannel.soundTransform = new SoundTransform(currentVol); // 当音量降到0时,停止音频和Timer if (currentVol <= 0) { mysoundchannel.stop(); soundtimer.stop(); soundtimer.removeEventListener(TimerEvent.TIMER, onTimerTick); } } }
代码说明
- Timer间隔设置:用20ms间隔比1000ms更平滑,避免音量突变。
- 淡出步长:
fadeStep=0.02配合20ms间隔,每秒降低1的音量,可根据需求调整步长或间隔来控制淡出速度。 - 播放进度判断:通过
SoundChannel.position获取当前播放时长,对比半程时间点触发淡出逻辑。 - 边界处理:用
Math.max确保音量不会低于0,避免出现负音量的异常情况。
内容的提问来源于stack exchange,提问作者Dika Atmaj
相关产品推荐
相关产品推荐

