cc.audioEngine.setCurrentTime 调用后音频设置的播放完成回调丢失

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

补充一下,_onendedSecond 方法中 self._onended(); 是我自己加,加上这个调用就好了,但是还是引擎大佬看下吧