H5音訊樣式修改,拖拽、點選進度操作、總時長載入
阿新 • • 發佈:2018-12-25
<audio/>標籤樣式修改
修改原因:
不同手機展示的樣式不同,特別是IOS 和安卓區別很大,需要統一樣式。
修改後樣式:
修改理解:
1>“點選播放”和"點選暫停" 呼叫原生audio.play() 和 audio.pause()來對進度條進行操作
2>總時長載入:解析 audio.duration 來獲取總時長,會有部分瀏覽器相容問題,下面列舉部分相容方式。
3>點選跳轉進度:獲取當前的 滑鼠點選位置【e.pageX】 - 進度條.offsetLeft【相對於它的直接父元素 的 偏移量】,使用 translateX 改變 “藍色小球”的播放進度位置。
4>拖拽跳轉進度:監聽 onTouchStart 、 onTouchMove 和 onTouchEnd
5> 目前缺點:
A.只有點選 進度條 才能跳轉進度,建議擴大面積
B.拖拽需要鬆手的時候才有效果
C.部分 安卓 UC瀏覽器,不能愉快的載入時間,只能點選播放才能載入【已經做了其他的相容】
核心程式碼:
轉換音訊時長顯示
/** * 工具類 */ //轉換音訊時長顯示 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 }
獲取視訊總長
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, }); }
更新播放進度
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,
});
}
進度條操作,拖拽和點選都需要呼叫
/**
* 進度條操作
* @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();
}
}
進度條拖拽相關
// 進度條點選
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上的獲取到時長
相容性測試:
相容瀏覽器包括: QQ瀏覽器、微信、手淘、百度瀏覽器、UC相容手機包括: IPhone7, IPhone6s, 華為P8Max,小米5,OPPO R9, vivo Xplay5A ,小米 MI5 ,魅族 note2,樂視 X900