子組件
<template>
? <div class="audio-wrapper">
? ? <audio ref="audio">
? ? ? <source :src="myAudioUrl" type="audio/mp3" />
? ? </audio>
? ? <div class="audio-left">
? ? ? <img
? ? ? ? ref="audioPlayer"
? ? ? ? v-if="myPlayTemp"
? ? ? ? @click="myPlay()"
? ? ? ? src="../../../../static/images/icon-播放.png"
? ? ? />
? ? ? <img
? ? ? ? ref="audioPlayer"
? ? ? ? v-if="!myPlayTemp"
? ? ? ? @click="myPlay()"
? ? ? ? src="../../../../static/images/icon-暫停.png"
? ? ? />
? ? </div>
? ? <div class="audio-right">
? ? ? <!-- <p style="max-width: 536px;"></p> -->
? ? ? <div class="audio-time">
? ? ? ? <span class="audio-length-current" ref="audioCurTime">00:00</span>
? ? ? ? <div class="progress-bar-bg" ref="progressBarBg" @mousedown="handledown()">
? ? ? ? ? <span ref="progressDot"></span>
? ? ? ? ? <div class="progress-bar" ref="progressBar"></div>
? ? ? ? </div>
? ? ? ? <span class="audio-length-total" ref="duration">00:00</span>
? ? ? </div>
? ? </div>
? </div>
</template>
<script>
export default {
? name: "myAudio",
? props: ["myAudioUrl"],
? data() {
? ? return {
? ? ? audio: "",
? ? ? myPlayTemp: true
? ? };
? },
? mounted() {
? ? this.init();
? },
? methods: {
? ? init() {
? ? ? this.audio = this.$refs.audio;
? ? ? this.audio.load();
? ? ? this.audio.pause();
? ? ? this.updateProgress();
? ? },
? ? // 點(diǎn)擊播放/暫停圖片時绵患,控制音樂的播放與暫停
? ? myPlay() {
? ? ? if (this.audio.paused) {
? ? ? ? // 開始播放當(dāng)前點(diǎn)擊的音頻
? ? ? ? this.audio.play();
? ? ? ? this.myPlayTemp = false;
? ? ? } else {
? ? ? ? this.audio.pause();
? ? ? ? this.myPlayTemp = true;
? ? ? }
? ? ? this.updateProgress();
? ? },
? ? // 更新進(jìn)度條與當(dāng)前播放時間
? ? updateProgress() {
? ? ? let value = this.audio.currentTime / this.audio.duration;
? ? ? this.$refs.progressBar.style.width = value * 100 + "%";
? ? ? this.$refs.progressDot.style.left = value * 100 + "%";
? ? ? // 初始時間
? ? ? this.$refs.audioCurTime.innerHTML = this.transTime(this.audio.currentTime);
? ? ? // 總共時長
? ? ? let audioElement = new Audio(this.myAudioUrl);
? ? ? let self = this
? ? ? audioElement.addEventListener("loadedmetadata", function () {
? ? ? ? let duration2 = (audioElement.duration / 100).toFixed(2).replace('.',':');
? ? ? ? self.$refs.duration.innerHTML = self.formatTime(duration2);
? ? ? });
? ? },
? ? // 播放結(jié)束時
? ? audioEnded() {
? ? ? this.$refs.progressBar.style.width = 0 + "%";
? ? ? this.$refs.progressDot.style.left = 0 + "%";
? ? ? this.myPlayTemp = true;
? ? },
? ? // 播放時間換算
? ? transTime(value) {
? ? ? let time = "";
? ? ? let h = parseInt(value / 3600);
? ? ? value %= 3600;
? ? ? let m = parseInt(value / 60);
? ? ? let s = parseInt(value % 60);
? ? ? if (h > 0) {
? ? ? ? time = this.formatTime(h + ":" + m + ":" + s);
? ? ? } else {
? ? ? ? time = this.formatTime(m + ":" + s);
? ? ? }
? ? ? return time;
? ? },
? ? //? * 格式化時間顯示膜钓,補(bǔ)零對齊
? ? //? * eg:2:4? -->? 02:04
? ? formatTime(value) {
? ? ? let time = "";
? ? ? let s = value.split(":");
? ? ? let i = 0;
? ? ? for (; i < s.length - 1; i++) {
? ? ? ? time += s[i].length == 1 ? "0" + s[i] : s[i];
? ? ? ? time += ":";
? ? ? }
? ? ? time += s[i].length == 1 ? "0" + s[i] : s[i];
? ? ? return time;
? ? },
? ? // 點(diǎn)擊進(jìn)度條跳到指定點(diǎn)播放
? ? handledown() {
? ? ? // 只有音樂開始播放后才可以調(diào)節(jié)爵卒,已經(jīng)播放過但暫停了的也可以
? ? ? console.log(this.audio.currentTime);
? ? ? if (!this.audio.paused || this.audio.currentTime != 0) {
? ? ? ? let pgsWidth = this.$refs.progressBarBg.offsetWidth;
? ? ? ? let rate = event.offsetX / pgsWidth;
? ? ? ? this.audio.currentTime = this.audio.duration * rate;
? ? ? ? this.updateProgress();
? ? ? }
? ? }
? },
? watch: {
? ? audio: function(params) {
? ? ? let self = this;
? ? ? self.audio.addEventListener(
? ? ? ? "timeupdate",
? ? ? ? function() {
? ? ? ? ? // console.log('開始');
? ? ? ? ? self.updateProgress();
? ? ? ? },
? ? ? ? false
? ? ? );
? ? ? self.audio.addEventListener(
? ? ? ? "ended",
? ? ? ? function() {
? ? ? ? ? // console.log('結(jié)束');
? ? ? ? ? self.audioEnded();
? ? ? ? },
? ? ? ? false
? ? ? );
? ? }
? }
};
</script>
<style lang="scss" scoped>
.audio-wrapper {
? background-color: #f8f8f8;
? margin: 10px auto;
? width: 70%;
? height: 50px;
? border-radius: 50px;
}
.audio-left {
? float: left;
? text-align: center;
? width: 15%;
? height: 100%;
}
.audio-left img {
? width: 40px;
? position: relative;
? top: 50%;
? transform: translateY(-50%);
? margin: 0;
? cursor: pointer;
}
.audio-right {
? float: left;
? width: 80%;
? height: 100%;
}
.progress-bar-bg {
? background-color: #d9d9d9;
? position: relative;
? height: 2px;
? cursor: pointer;
}
.progress-bar {
? background-color: #649fec;
? width: 0;
? height: 2px;
}
.progress-bar-bg span {
? content: " ";
? width: 10px;
? height: 10px;
? border-radius: 50%;
? -moz-border-radius: 50%;
? -webkit-border-radius: 50%;
? background-color: #3e87e8;
? position: absolute;
? left: 0;
? top: 50%;
? margin-top: -5px;
? margin-left: -5px;
? cursor: pointer;
}
.audio-time {
? margin-top: 5%;
}
.audio-length-total {
? float: right;
? font-size: 12px;
}
.audio-length-current {
? float: left;
? font-size: 12px;
}
</style>
父組件關(guān)鍵代碼(用來監(jiān)聽element彈框喳魏,取消播放并復(fù)位)
<myAudio ref="myAudioOne" :myAudioUrl="errorDetailInfo.audios"></myAudio>
watch: {
? ? ? 'dialogVisible':function (val) {
? ? ? ? const self = this
? ? ? ? self.$refs.myAudioOne.init();
? ? ? ? self.$refs.myAudioOne.audioEnded();
? ? ? ? }
? ? },