cocosCreator 版本2.4.13
播放代码如下
const id = cc.audioEngine.playEffect(this.audioClip, false);
const onFinish = () => {
console.log("音频播放完成,ID:", id);
}
cc.audioEngine.setFinishCallback(id, onFinish);
cc.audioEngine.setCurrentTime(id, 0.2);
- 一旦调用 setCurrentTime onFinish 就不会触发
- 查看引擎源码 CCAudio.js 得知
let Audio = function (src) {
EventTarget.call(this);
this._shouldRecycleOnEnded = false;
this._src = src;
this._element = null;
this.id = 0;
this._state = Audio.State.INITIALZING;
const self = this;
this._onended = function () {
self._state = Audio.State.STOPPED;
self.emit('ended');
};
this._onendedSecond = function () {
self._unbindEnded(self._onendedSecond);
console.log('_onendedSecond')
self._bindEnded();
self._onended();
};
};
- 其中 _onendedSecond 在设置音频时长时会覆盖原结束回调,使用 _onendedSecond
proto.setCurrentTime = function (num) {
let self = this;
this._src && this._src._ensureLoaded(function () {
// setCurrentTime would fire 'ended' event
// so we need to change the callback to rebind ended callback after setCurrentTime
self._unbindEnded();
self._bindEnded(self._onendedSecond);
self._element.currentTime = num;
});
};
- 上述代码可知,setCurrentTime 先解绑了原结束回调让结束逻辑走自己内部的 _onendedSecond
- 看注释貌似这样做是有兼容问题,可能element.currentTime = num设置时长时会调用完成回调因此强制走内部的
- 但是
this._onendedSecond = function () {
self._unbindEnded(self._onendedSecond);
console.log('_onendedSecond')
self._bindEnded();
self._onended();
};
- 其中走到 _onendedSecond 结束事件已经触发过了此时在 self._onended(); 绑定回原回调不会触发啊
- 也就是 _onended 方法没有走,没有触发 self.emit(‘ended’);
- 代码很简单,希望官方看下这个是否是已知问题刻意为之还是是个逻辑bug