mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-01-15 15:31:08 +00:00
171 lines
4.8 KiB
JavaScript
171 lines
4.8 KiB
JavaScript
|
const game = cc.game;
|
||
|
const EventTarget = cc.EventTarget;
|
||
|
|
||
|
const State = {
|
||
|
ERROR: -1,
|
||
|
INITIALZING: 0,
|
||
|
PLAYING: 1,
|
||
|
PAUSED: 2,
|
||
|
STOPPED: 3,
|
||
|
}
|
||
|
|
||
|
function Audio (url, serializedDuration) {
|
||
|
this._nativeAudio = my.createInnerAudioContext();
|
||
|
this._et = new EventTarget();
|
||
|
this.reset();
|
||
|
this._setSrc(url);
|
||
|
const nativeAudio = this._nativeAudio;
|
||
|
this._serializedDuration = serializedDuration;
|
||
|
this._ensureLoaded(() => {
|
||
|
this._duration = nativeAudio.duration;
|
||
|
});
|
||
|
this._duration = 1;
|
||
|
this._onShow = () => {
|
||
|
if (this._blocked) {
|
||
|
this._nativeAudio.play();
|
||
|
}
|
||
|
this._blocked = false;
|
||
|
};
|
||
|
this._onHide = () => {
|
||
|
if (this.getState() === State.PLAYING) {
|
||
|
this._nativeAudio.pause();
|
||
|
this._blocked = true;
|
||
|
}
|
||
|
};
|
||
|
nativeAudio.onCanplay(() => { this._et.emit('load'); });
|
||
|
nativeAudio.onError((err) => { this._et.emit('error', err); });
|
||
|
nativeAudio.onEnded(() => {
|
||
|
this.finishCB && this.finishCB();
|
||
|
this._state = State.INITIALZING;
|
||
|
this._et.emit('ended');
|
||
|
});
|
||
|
nativeAudio.onStop(() => { this._et.emit('stop'); });
|
||
|
nativeAudio.onTimeUpdate(() => { this._currentTime = nativeAudio.currentTime; });
|
||
|
game.on(game.EVENT_SHOW, this._onShow);
|
||
|
game.on(game.EVENT_HIDE, this._onHide);
|
||
|
this.onError((err) => { cc.error(err); });
|
||
|
}
|
||
|
|
||
|
Audio.State = State;
|
||
|
|
||
|
Object.assign(Audio.prototype, {
|
||
|
|
||
|
reset () {
|
||
|
this.id = -1;
|
||
|
this.finishCB = null; // For audioEngine custom ended callback.
|
||
|
this._state = State.INITIALZING;
|
||
|
this._loop = false;
|
||
|
this._currentTime = 0;
|
||
|
this._volume = 1;
|
||
|
this._blocked = false;
|
||
|
this._loaded = false;
|
||
|
|
||
|
this.offLoad();
|
||
|
this.offError();
|
||
|
this.offEnded();
|
||
|
this.offStop();
|
||
|
},
|
||
|
|
||
|
destroy () {
|
||
|
this.reset();
|
||
|
game.off(game.EVENT_SHOW, this._onShow);
|
||
|
game.off(game.EVENT_HIDE, this._onHide);
|
||
|
// offCanplay offOnError offStop offEnded is not supported for now.
|
||
|
|
||
|
this._nativeAudio.destroy();
|
||
|
this._nativeAudio = null;
|
||
|
},
|
||
|
|
||
|
getSrc () { return this._src; },
|
||
|
// NOTE: don't set src twice, which is not supported on TAOBAO
|
||
|
_setSrc (path) {
|
||
|
if (this._src === path) {
|
||
|
return;
|
||
|
}
|
||
|
const nativeAudio = this._nativeAudio;
|
||
|
this._loaded = false;
|
||
|
nativeAudio.src = path;
|
||
|
this._src = path;
|
||
|
},
|
||
|
getState () { return this._state; },
|
||
|
getDuration () { return this._serializedDuration ? this._serializedDuration : this._duration; },
|
||
|
getCurrentTime () { return this._currentTime; },
|
||
|
seek (val) {
|
||
|
if (this._currentTime === val) {
|
||
|
return;
|
||
|
}
|
||
|
this._ensureLoaded(() => {
|
||
|
this._nativeAudio.seek(val);
|
||
|
this._currentTime = val;
|
||
|
});
|
||
|
},
|
||
|
getLoop () { return this._loop; },
|
||
|
setLoop (val) {
|
||
|
if (this._loop === val) {
|
||
|
return;
|
||
|
}
|
||
|
this._ensureLoaded(() => {
|
||
|
this._nativeAudio.loop = val;
|
||
|
this._loop = val;
|
||
|
});
|
||
|
},
|
||
|
getVolume () { return this._volume; },
|
||
|
setVolume (val) {
|
||
|
if (this._volume === val) {
|
||
|
return;
|
||
|
}
|
||
|
this._ensureLoaded(() => {
|
||
|
this._nativeAudio.volume = val;
|
||
|
this._volume = val;
|
||
|
});
|
||
|
},
|
||
|
|
||
|
play () {
|
||
|
if (this.getState() !== State.PLAYING) {
|
||
|
this._nativeAudio.play();
|
||
|
this._state = State.PLAYING;
|
||
|
}
|
||
|
},
|
||
|
resume () {
|
||
|
if (this.getState() === State.PAUSED) {
|
||
|
this._nativeAudio.play();
|
||
|
this._state = State.PLAYING;
|
||
|
}
|
||
|
},
|
||
|
pause () {
|
||
|
if (this.getState() === State.PLAYING) {
|
||
|
this._nativeAudio.pause();
|
||
|
this._state = State.PAUSED;
|
||
|
}
|
||
|
},
|
||
|
stop () {
|
||
|
// NOTE: On taobao, it is designed that audio is useless after stopping.
|
||
|
// this._nativeAudio.stop();
|
||
|
this._nativeAudio.pause();
|
||
|
this._nativeAudio.seek(0);
|
||
|
this._state = State.STOPPED;
|
||
|
},
|
||
|
|
||
|
onceLoad (cb) { this._et.once('load', cb); },
|
||
|
onLoad (cb) { this._et.on('load', cb); },
|
||
|
offLoad (cb = undefined) { this._et.off('load', cb); },
|
||
|
onError (cb) { this._et.on('error', cb); },
|
||
|
offError (cb = undefined) { this._et.off('error', cb); },
|
||
|
onEnded (cb) { this._et.on('ended', cb); },
|
||
|
offEnded (cb = undefined) { this._et.off('ended', cb); },
|
||
|
onStop (cb) { this._et.on('stop', cb); },
|
||
|
offStop (cb = undefined) { this._et.off('stop', cb); },
|
||
|
|
||
|
_ensureLoaded (cb) {
|
||
|
if (this._loaded) {
|
||
|
cb();
|
||
|
} else {
|
||
|
this.onceLoad(() => {
|
||
|
this._loaded = true;
|
||
|
cb();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
module.exports = Audio;
|