vue实现自定义音乐播放器
项目中遇到了,让实现一个音乐播放器的功能。修改其样式要求自定义,切需要有,进度条,时间,开关,应用于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函数