项目中遇到了,让实现一个音乐播放器的功能。修改其样式要求自定义,切需要有,进度条,时间,开关,应用于H5需要兼容ios与android。简单看一下如图播放器
完成代码
audioCom.vue
<template>
<div class="myaudio">
<audio
@timeupdate="updateProgress"
controls
ref="audioRef"
style="display: none"
@canplay="getDuration"
>
<source :src="fileurl" type="audio/mpeg" />
您的浏览器不支持音频播放
</audio>
<div class="audioPanel">
<div class="playBtn" @click="playAudio">
<img
v-show="audioStatus == 0"
src="@/assets/images/main/icon_play.png"
alt=""
/>
<img
v-show="audioStatus == 1"
src="@/assets/images/main/icon_stop.png"
alt=""
/>
</div>
<div class="slidList">
<van-progress color="#51C0F0" class="sliderr" :percentage="value" />
<span class="timers">{{ videoStart }}/{{ transTime(duration) }}</span>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
// 播放地址
fileurl: {
type: String,
default: "",
},
},
data: function () {
return {
audioStatus: 0,
videoStart: "00:00",
value: 0,
duration: 0,
isToPla:false
};
},
mounted() {
if (this.fileurl&&!this.isToPla) {
this.$nextTick(() => {
document.addEventListener(
"touchstart",
() => {
if(this.isToPla){
return
}
this.$refs.audioRef.play();
this.$refs.audioRef.pause();
},
false
);
});
}
},
methods: {
getDuration() {
this.duration = this.$refs.audioRef.duration;
},
//播放暂停控制
playAudio(e) {this.isToPla=true
let recordAudio = this.$refs.audioRef; //获取audio元素
if (recordAudio.paused) {
recordAudio.play();
this.audioStatus = 1;
} else {
recordAudio.pause();
this.audioStatus = 0;
}
},
//更新进度条与当前播放时间
updateProgress(e) {
var value = e.target.currentTime / this.duration;
this.value = value * 100;
if (e.target.currentTime > this.duration) {
this.audioStatus = 0;
this.value = 0;
this.videoStart = this.transTime(0);
return;
}
this.value = value * 100;
this.videoStart = this.transTime(this.$refs.audioRef.currentTime);
},
/**
* 音频播放时间换算
* @param {number} value - 音频当前播放时间,单位秒
*/
transTime(value) {
var time = "";
var h = parseInt(value / 3600);
value %= 3600;
var m = parseInt(value / 60);
m = m < 10 ? "0" + m : m;
var s = parseInt(value % 60);
s = s < 10 ? "0" + s : s;
time = m + ":" + s;
return time;
},
// 进度条
onChange(val) {
let recordAudio = this.$refs.audioRef; //获取audio元素
if (!recordAudio.paused || recordAudio.currentTime != 0) {
recordAudio.currentTime = (recordAudio.duration * val) / 100;
this.videoStart = this.transTime((val / 100) * this.duration);
}
},
},
};
</script>
<style lang="scss" scoped>
.audioPanel {
display: flex;
align-items: center;
height: 40px;
.slidList {
position: relative;
flex: 1;
.timers {
color: #bdbdbd;
font-family: PingFang SC;
font-size: 12px;
text-align: left;
position: absolute;
top: 10px;
right: 0px;
}
}
.sliderr {
width: 100%;
}
.playBtn {
height: 30px;
img {
height: 100%;
}
}
}
::v-deep {
.van-progress__pivot {
display: none;
}
}
</style>
为了更好地处理IOS duration兼容问题
我们在mounted中添加了自动触发touchstart方法,去进入页面触发一次,这里goole新版本不允许立即播放,会抛出异常,但无关紧要。
mounted() {
if (this.fileurl&&!this.isToPla) {
this.$nextTick(() => {
document.addEventListener(
"touchstart",
() => {
if(this.isToPla){
return
}
this.$refs.audioRef.play();
this.$refs.audioRef.pause();
},
false
);
});
}
},
isToPla:目的是触发一次后停止继续触发该touch函数