H5音频<audio/>样式修改,拖拽、点击进度操作,总时长 during 加载【React 】

前端之家收集整理的这篇文章主要介绍了H5音频<audio/>样式修改,拖拽、点击进度操作,总时长 during 加载【React 】前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

H5音频<audio/>自定义样式,拖拽、点击改变进度操作,总时长 during 加载


兼容性测试:

兼容浏览器包括
QQ浏览器、微信、手淘、百度浏览器、UC

兼容手机包括
IPhone7,IPhone6s,华为P8Max,小米5,OPPO R9,vivo Xplay5A,小米 MI5,魅族 note2,乐视 X900



<audio/>标签样式修改

修改原因:

不同手机展示的样式不同,特别是IOS 和安卓区别很大,需要统一样式。


修改后样式:




修改理解:

1>“点击播放”和"点击暂停" 调用原生audio.play() 和audio.pause()来对进度条进行操作

2>总时长加载:解析 audio.duration 来获取总时长,会有部分浏览器兼容问题,下面列举部分兼容方式。

3>点击跳转进度:获取当前的 鼠标点击位置【e.pageX】 - 进度条.offsetLeft【相对于它的直接父元素 的 偏移量】,使用 translateX 改变 “蓝色小球”的播放进度位置。

4>拖拽跳转进度:监听 onTouchStart 、onTouchMove 和onTouchEnd

5> 目前缺点:

A.只有点击 进度条 才能跳转进度,建议扩大面积

B.拖拽需要松手的时候才有效果

C.部分 安卓 UC浏览器,不能愉快的加载时间,只能点击播放才能加载【已经做了其他的兼容】



核心代码


转换音频时长显示

@H_404_134@ /** * 工具类 */ //转换音频时长显示 transTime(time) { let duration = parseInt(time); let minute = parseInt(duration / 60); let sec = duration % 60 + ''; let isM0 = ':'; if (minute == 0) { minute = '00'; } else if (minute < 10) { minute = '0' + minute; } if (sec.length == 1) { sec = '0' + sec; } return minute + isM0 + sec }


获取视频总长

@H_404_134@ loadVideo() { let self = this; let audio = this.refs.audioTag; let duration = this.transTime(audio.duration); let time = duration == "NaN:NaN" ? "00:00" : duration; // alert(audio.duration); if (time == "00:00" && duration != "NaN:NaN" && !!initAudio) { audio.play(); audio.pause(); initAudio = false; window.setTimeout(() => { self.loadVideo(); },300); } this.setState({ voiceDuration: time,}); }

更新播放进度

@H_404_134@ timeUpdate() { let audio = this.refs.audioTag; // let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100,0); // console.log("timeUpdate " + value); let timeline = this.refs.timeline; let playhead = this.refs.playhead; let timelineWidth = timeline.offsetWidth - playhead.offsetWidth; let playPercent = timelineWidth * (audio.currentTime / audio.duration); playhead.style.webkitTransform = "translateX(" + playPercent + "px)"; playhead.style.transform = "translateX(" + playPercent + "px)"; let timeCurrent = this.transTime(audio.currentTime); this.setState({ timeCurrent: timeCurrent,currentTime: audio.currentTime,}); }

进度条操作,拖拽和点击都需要调用

@H_404_134@/** * 进度条操作 * @param {[type]} e [description] * @return {[type]} [description] */ timelineClick(e) { let timeline = this.refs.timeline; let playhead = this.refs.playhead; let audio = this.refs.audioTag; let timelineWidth = timeline.offsetWidth - playhead.offsetWidth; // 更新坐标位置 // e.pageX 鼠标点击位置 // offsetLeft 元素 相对于它的直接父元素 的 偏移量 let newLeft = e.pageX - timeline.offsetParent.offsetLeft; let currentTime = audio.duration * (e.pageX - timeline.offsetParent.offsetLeft) / timelineWidth; if (newLeft >= 0 && newLeft <= timelineWidth) { playhead.style.transform = "translateX(" + newLeft + "px)"; } if (newLeft < 0) { playhead.style.transform = "translateX(0)"; currentTime = 0; } if (newLeft > timelineWidth) { playhead.style.transform = "translateX(" + timelineWidth + "px)"; currentTime = audio.duration; } // 更新时间 let timeCurrent = this.transTime(currentTime); this.setState({ timeCurrent: timeCurrent,currentTime: currentTime,}); // 如果在播放 if (this.state.isPlay) { audio.currentTime = currentTime; audio.play(); } else { // pause music audio.pause(); } }

进度条拖拽相关

@H_404_134@ // 进度条点击 touchStart(e) { let events = e.touches[0] || e; this.timelineClick(events); } touchMove(e) { // if (this.state.touching !== true) { // return; // } let events = e.touches[0] || e; this.timelineClick(events); } touchEnd(e) { this.setState({ touching: false,}) }

HTML代码

          <div className="inline-block voice-container">
            <audio  ref="audioTag" src={this.state.voice} onTimeUpdate={()=>this.timeUpdate()} onLoadedMetadata={()=>this.loadVideo()}/>
            <div className="controls">
              <div className="fake-control">
                <div  className="inline-block fake-control-timeline" >
                  <div ref="timeline" className="timeline inline-block" onClick={(e)=> this.timelineClick(e)} > 
                      <div ref="playhead" className="playhead" onTouchStart={(e)=>this.touchStart(e)} onTouchMove={(e)=>this.touchMove(e)} onTouchEnd={(e)=>this.touchEnd(e)}></div>
                  </div>
                  
                  <div className="inline-block play-time">
                    <div className="inline-block played-time">{this.state.timeCurrent}</div>
                    <div className="inline-block">/</div>
                    <div className="inline-block audio-time" id="audioTime">{this.state.voiceDuration}</div>
                  </div> 
                </div>
                <div className="inline-block voice-control">
                  <a className="play-pause" id="playPause" onClick={()=>this.play()}>
                    <div className="play-icon">{ this.state.isPlay ? stop : play }</div>
                  </a>
                </div>
              </div>
            </div>
            
          </div>


CSS代码就不具体粘贴了~可以看下面的demo调试~



踩的坑:

不能愉快的加载音频的时长


采取兼容方式:

1>第一次没有加载出来时间的时候,自动调用一次。

2>采用 播放、暂停的方式,获取到 总时长

3>部分机型vivo Xplay5A 等,没有办法在UC上的获取到时长


DEMO 演示地址:

https://codepen.io/CandyQiu/pen/VMOPaw?editors=0110

原文链接:https://www.f2er.com/react/302459.html

猜你在找的React相关文章