html
<div class="text_audio" v-if="audio_url">
<div class="audio_info">
<div class="audio_schedule_box"
@touchstart='progressTouchstart'
@touchend='progressTouchend'
@touchmove='progressTouchmove'>
<div class="audio_schedule" :style="{width:audioPosition+'%'}"></div>
</div>
<div class="audio_time">
<span>{{currentTime}}</span>
<span>{{duration || '00:00'}}</span>
</div>
</div>
<div class="audio_play" @click="playAudio">
<image src="../../static/images/articleDetailPlay.png" v-if="isPlay"></image>
<image src="../../static/images/articleDetailPause.png" v-else></image>
</div>
</div>
data(){
return{
// 创建的音频实例
audio:null,
// 当前音频播放时间点
currentTime:'00:00',
// 音频时长
duration:'',
// 音频播放位置
audioPosition:0,
// 是否第一次播放
isFirstPlay:false,
// 是否播放
isPlay:false,
// 起点位置left
positionL:0,
// 起点位置right
positionR:0,
// 移动的位置
clientX:0,
// 滚动距离顶部位置
scrollTop:0,
audio_url: "https://img.taotaoling.com/files/4afeeddff5e01e16ed59a6bab3a831d0.mp3"
}
},
methods:{
progressTouchstart(e){
if(!this.audio) return;
this.audio.pause();
// 获取audio_schedule_box 在页面的位置
let info = uni.createSelectorQuery().in(this).select('.audio_schedule_box');
info.boundingClientRect((data) => {
this.positionL = Number(data.left);
this.positionR = Number(data.right);
this.clientX = Number(e.touches[0].clientX);
let num = this.clientX - this.positionL;
this.audio.seek(num);
// 获取元素信息
}).exec()
},
progressTouchmove(e){
//计算手指滑动的距离
if(!this.audio) return;
this.audio.pause();
this.clientX = Number(e.touches[0].clientX);
let num = this.clientX - this.positionL;
if(this.clientX < 0 || this.clientX > this.positionR) {
num = this.positionR;
}
this.audio.seek(num);
},
progressTouchend(e){
if(this.isPlay){
this.audio.play();
}
},
playAudio(){
this.videoContext.pause();
if(this.isFirstPlay && this.articleData.audio_url) {
/**
* 解决 uni.getBackgroundAudioManager() 暂停无效问题
* */
this.createAudio();
this.isPlay = true;
this.isFirstPlay = false;
}else {
// 点击播放暂停按钮
if(this.audio.paused){
this.audio.play();
this.isPlay = true;
}else {
this.audio.pause();
this.isPlay = false;
}
}
},
createAudio(){
this.audio = uni.getBackgroundAudioManager();
// 一定要赋值 否则会报错
this.audio.title = '标题';
this.audio.src = this.audio_url;
this.audio.onPlay((e) => {
this.duration = this.transTime(this.audio.duration);
});
this.audio.onTimeUpdate((e) => {
// 获取音频当前事件
this.currentTime = this.transTime(this.audio.currentTime);
// 音频进度条
this.audioPosition = Math.round(this.audio.currentTime / this.audio.duration * 10000) / 100.00
});
this.audio.onEnded((res) => {
this.isFirstPlay = true;
this.isPlay = false;
});
this.audio.onError((res) => {
wx.showToast({
title: "音频加载失败",
icon: "none",
});
});
},
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
},
}
onHide(){
if(this.audio) {
this.audio.stop();
}
},
onUnload(){
if(this.audio) {
this.audio.stop();
}
},
css
.text_audio {
height: 167px;
background: #F2F2F2;
border-radius: 20px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 60px 0 26px;
margin-top: 40px;
.audio_info {
width: 467px;
position: relative;
.audio_schedule_box {
width: 431px;
height: 24px;
background: #000000;
opacity: 0.3;
border-radius: 12px;
display: flex;
align-items: center;
padding: 0 5px;
margin: auto;
overflow: hidden;
.audio_schedule {
height: 16px;
border-radius: 8px;
overflow: hidden;
background: linear-gradient(43deg, #FEDD95, #FFE8BF);
transition:all .1s;
}
}
.audio_time {
position: absolute;
bottom: -35px;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
color: #333333;
font-weight: bold;
font-size: 22px;
}
}
.audio_play {
width: 60px;
height: 60px;
image {
width: 100%;
height: 100%;
}
}
}
音频.png