1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > html仿微信语音播放器 原生js仿微信音频播放器

html仿微信语音播放器 原生js仿微信音频播放器

时间:2024-07-02 12:16:36

相关推荐

html仿微信语音播放器 原生js仿微信音频播放器

今天看个类似微信音频播放器的效果:

简单使用

使用比较简单,直接配置如下:

varwx_audio=newWxAudio({

ele:".wx-audio",

title:music[0].title,

disc:music[0].descr,

src:music[0].src,

loop:0,

width:"320px",

ended:function(){

wx_audio.audioCut(music[1].src,music[1].title,music[1].descr)

},

});

一些API如下:

document.getElementById("play").onclick=function(){

wx_audio.audioPlay()

},document.getElementById("pause").onclick=function(){

wx_audio.audioPause()

},document.getElementById("cut").onclick=function(){

wx_audio.audioCut(music[1].src,music[1].title,music[1].descr)

}

进度条相关

源码里的进度条有好几个,先看看相关代码:

//实际播放进度条

this.wxVoiceP=document.createElement("span");

this.wxVoiceP.className="wx-voice-p";

this.wxAudioDetail.appendChild(this.wxVoiceP);

//缓冲进度条

this.wxBufferP=document.createElement("span");

this.wxBufferP.className="wx-buffer-p";

this.wxAudioDetail.appendChild(this.wxBufferP);

//进度条loading容器,

this.wxLoading=document.createElement("span");

this.wxLoading.className="wx-loading";

this.wxAudioDetail.appendChild(this.wxLoading);

//进度条上的loading效果

this.wxLoadingWrapper=document.createElement("span");

this.wxLoadingWrapper.className="wx-loading-wrapper";

this.wxLoading.appendChild(this.wxLoadingWrapper);

//进度条上的小圆点

this.wxAudioOrigin=document.createElement("div");

this.wxAudioOrigin.className="wx-audio-origin";

this.wxAudioP.appendChild(this.wxAudioOrigin);

wxVoiceP代表的是实际播放的进度条,它和wxAudioOrigin(小圆点)的进度是一致的。

wxBufferP代表的是缓冲进度条,它和播放进度不太一样,它一般会在当前播放点多缓冲一些。

wxLoading代表的是一个在进度条上的loading,如果出现等待的情况,会显示它。

Dom结构如下:

播放器上的事件

播放器上有很多事件,让我们一起来解读一下:

i.wxAudio.onplaying=function(){//播放

console.log('playing')

vart=newDate;

i.isPlaying=1;//设置播放标志

i.reduceTBefore=Date.parse(t)-Math.floor(1e3*i.wxAudio.currentTime);

console.log('reduceTBefore',newDate(i.reduceTBefore).format('YY-MM-DDHH:mm:ss'))

i.wxAudioStateImg.src=o//切换图片,变成播放的gif

}

播放音频的时候触发一次,上面reduceTBefore记录的是当前时间相对于当前播放时间的时间差,这个值比较有意思,如果音频一直流畅播放,那么这个值是不变的,因为当前时间在递增,当前播放时间也在递增。

i.wxAudio.onpause=function(){//暂停

i.isPlaying=0;

i.showLoading(0);

i.wxAudioStateImg.src=n;

}

暂停的时候,进度条关闭loading。

i.wxAudio.onloadedmetadata=function(){//资源加载完毕

console.log('onloadedmetadata')

i.durationT=i.wxAudio.duration;

i.wxAudioDuration.innerText=i.formartTime(i.wxAudio.duration);//de

}

资源加载完毕,显示音频的总时间durationT。

i.wxAudio.onwaiting=function(){

console.log('onwaiting')

if(i.wxAudio.paused==0){

i.showLoading(1)

}

}

当发生卡顿或者点击未播放过的进度条,会出发onwating,若此时正在播放,进度条会显示loading。

i.wxAudio.onprogress=function(){

console.log('process')

if(i.wxAudio.buffered.length>0){

for(vart=0,e=0;e

t+=i.wxAudio.buffered.end(e)-i.wxAudio.buffered.start(e);

if(t>i.durationT){

t=i.durationT;

i.showLoading(0);

}

}

varA=Math.floor(t/i.durationT*100);

i.wxBufferP.style.width=A+"%"

}

varo=newDate;

if(i.wxAudio.paused==0){

i.reduceTAfter=Date.parse(o)-Math.floor(1e3*i.currentT);

i.reduceTAfter-i.reduceTBefore>1e3?i.showLoading(1):i.showLoading(0)

console.log('reduceTAfter',newDate(i.reduceTAfter).format('YY-MM-DDHH:mm:ss'))

}

}

当音频发生下载的时候,会触发onprogress,将得到的buffered统计起来,更新缓冲进度条。

注意有一个reduceTAfter,它和reduceTBefore一样,也是得到当前时间相对于当前播放时间的一个值,reduceTAfter-reduceTBefore>1e3意思是当音频卡顿超过1s,就显示loading。

i.wxAudio.ontimeupdate=function(){

vart=newDate;

if(i.isDrag==0){

i.currentT=i.wxAudio.currentTime;

i.currentP=Number(i.wxAudio.currentTime/i.durationT*100);

i.reduceTBefore=Date.parse(t)-Math.floor(1e3*i.currentT);i.currentP=i.currentP>100?100:i.currentP;

i.wxVoiceP.style.width=i.currentP+"%";

i.wxAudioOrigin.style.left=i.currentP+"%";

i.wxAudioCurrent.innerText=i.formartTime(i.wxAudio.currentTime);

i.showLoading(0);

}

}

在声音一直在播放的时候,会一直触发ontimeupdate事件。会更新进度条额reduceTBefore。

i.wxAudioOrigin.onmousedown=function(t){

console.log('mousedown')

i.isDrag=1;

vare=(t||window.event).clientX,

A=t.target.offsetLeft;

i.maxProgressWidth=i.wxAudioDetail.offsetWidth;

i.wxAudioC.onmousemove=function(t){

if(i.isDrag){

varo=(t||window.event).clientX;

i.dragProgressTo=Math.min(i.maxProgressWidth,Math.max(0,A+(o-e)));

i.updatePorgress()

}

},i.wxAudioC.onmouseup=function(){

if(i.isDrag){

i.isDrag=0;

i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT)

}

},i.wxAudioC.onmouseleave=function(){

if(i.isDrag){

i.isDrag=0;

i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT)

}

}

}

i.wxAudioOrigin.ontouchstart=function(t){

console.log('touchstart')

i.isDrag=1;

vare=t||window.event,

A=e.touches[0].clientX,

o=e.target.offsetLeft;

i.maxProgressWidth=i.wxAudioDetail.offsetWidth;

i.wxAudioC.ontouchmove=function(t){

if(i.isDrag){

vare=(t||window.event).touches[0].clientX;

i.dragProgressTo=Math.min(i.maxProgressWidth,Math.max(0,o+(e-A)));

i.updatePorgress()

}

}

i.wxAudioC.ontouchend=function(){

if(i.isDrag){

i.isDrag=0;

i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT)

}

}

}

mousedown/mousemove/mouseup用来确定播放器的currentTIme;ontouchstart/ontouchmove/ontouchend是用来处理手机上的点击事件。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。