123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- enum PlayStatus {
- none,
- playBefore,
- play,
- playFail,
- pause
- }
- enum TriggerAudioListener {
- fail='fail',
- canplay='canplay',
- ended='ended',
- speed='speed',
- status='status'
- }
- class CustomAudio {
- audio:HTMLAudioElement = undefined;
- src:string = '';
- triggers:Record<string, any>={};
- status:PlayStatus = PlayStatus.none
- // 设置播放路径
- setSrc(src:string){
- if (!CustomAudio.supper) return;
- if (src && src !== this.src) {
- // 清空所有监听事件
- this.triggers = {};
- this.src = src;
- this.status = PlayStatus.none;
- if (this.audio === undefined) {
- this.audio = document.createElement('audio');
- this.audio.setAttribute('style','display:none');
- this.audio.src = src;
- // 播放结束
- this.audio.addEventListener('ended', ()=> {
- this.setStatus(PlayStatus.pause);
- return this.triggerListener(TriggerAudioListener.canplay,{
- duration: this.getDuration(this.audio.duration)
- });
- }, false);
- // 加载就绪
- this.audio.addEventListener('canplay', ()=> {
- return this.triggerListener(TriggerAudioListener.canplay,{
- duration: this.getDuration(this.audio.duration)
- });
- }, false);
- // 加载失败
- this.audio.addEventListener('error', ()=> {
- return this.triggerListener(TriggerAudioListener.fail,{
- message:'加载失败'
- });
- }, false);
- document.body.appendChild(this.audio);
- } else {
- this.audio.src = src;
- }
- }
- return this;
- }
- getDuration(duration:number){
- duration = parseFloat(duration.toFixed(2));
- return Math.floor(duration);
- }
- // 播放
- play(){
- if (!this.audio || this.status === PlayStatus.play || this.status === PlayStatus.playBefore) return;
- this.setStatus(PlayStatus.playBefore);
- this.audio.play().then(()=>{
- this.setStatus(PlayStatus.play);
- }).catch(()=>{
- this.setStatus(PlayStatus.playFail);
- });
- return this;
- }
- private triggerTime;
- triggerSpeed(){
- clearTimeout(this.triggerTime);
- let params = {
- duration: this.getDuration(this.audio.duration),
- currDuration: this.getDuration(this.audio.currentTime)
- };
- let diff = this.audio.duration - this.audio.currentTime;
- this.triggerListener(TriggerAudioListener.speed,params);
- if (diff > 0) {
- this.triggerTime = setTimeout(()=> this.triggerSpeed(),1000);
- } else {
- return ;
- }
- }
- // 暂停
- paused(){
- if (!this.audio || this.status === PlayStatus.pause) return;
- this.setStatus(PlayStatus.pause);
- this.audio.pause();
- return this;
- }
- setStatus(status:PlayStatus){
- if (this.status !== status) {
- this.status = status;
- if (status === PlayStatus.play) {
- this.triggerSpeed();
- } else {
- clearTimeout(this.triggerTime);
- }
- return this.triggerListener(TriggerAudioListener.status,status);
- }
- }
- addListener(key:TriggerAudioListener,callback:Function) {
- if (!callback) return;
- if (this.triggers[key] === undefined) this.triggers[key] = [callback];
- else this.triggers[key].push(callback);
- return this;
- }
- removeListener(key:TriggerAudioListener,callback:Function) {
- if (!callback || this.triggers[key] === undefined) return;
- let index = this.triggers[key].indexOf(callback);
- if (index>=0) this.triggers[key].splice(index,1);
- return this;
- }
- triggerListener(key:TriggerAudioListener,data?:any) {
- if (this.triggers[key]) {
- this.triggers[key].map((item)=> item && item(data));
- }
- }
- static supper:boolean = !!(document.createElement('audio').canPlayType)
- }
- export {CustomAudio,TriggerAudioListener,PlayStatus};
- export default new CustomAudio();
|