項目中遇到了,讓實現一個音樂播放器的功能。修改其樣式要求自定義,切需要有,進度條,時間,開關,應用於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函數