|
@@ -1,6 +1,12 @@
|
|
|
<template>
|
|
|
<div class="audio-wrapper">
|
|
|
- <span :class="[url ? 'audio-play' : 'audio-play not-url']" @click="playAudio">
|
|
|
+ <span
|
|
|
+ :class="[url ? 'audio-play' : 'audio-play not-url']"
|
|
|
+ :style="{
|
|
|
+ padding: showSlider ? '4px 16px' : '',
|
|
|
+ }"
|
|
|
+ @click="playAudio"
|
|
|
+ >
|
|
|
<SvgIcon v-if="audio.paused" :size="audio.paused ? 20 : 14" :icon-class="iconClass" />
|
|
|
<img
|
|
|
v-else
|
|
@@ -11,13 +17,34 @@
|
|
|
"
|
|
|
class="voice-play"
|
|
|
/>
|
|
|
+
|
|
|
+ <template v-if="showSlider">
|
|
|
+ <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
|
|
|
+ <el-slider
|
|
|
+ v-model="play_value"
|
|
|
+ class="audio-slider"
|
|
|
+ :format-tooltip="formatProcessToolTip"
|
|
|
+ @change="changeCurrentTime"
|
|
|
+ />
|
|
|
+ <span class="audio-time">{{ audio_allTime }}</span>
|
|
|
+ </template>
|
|
|
</span>
|
|
|
- <audio :id="fileId" :ref="fileId" :src="url" preload="metadata"></audio>
|
|
|
+
|
|
|
+ <audio
|
|
|
+ :id="fileId"
|
|
|
+ :ref="fileId"
|
|
|
+ :src="url"
|
|
|
+ preload="metadata"
|
|
|
+ @loadedmetadata="onLoadedmetadata"
|
|
|
+ @timeupdate="onTimeupdate"
|
|
|
+ @canplaythrough="oncanplaythrough"
|
|
|
+ ></audio>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { GetFileURLMap } from '@/api/app';
|
|
|
+import { secondFormatConversion } from '@/utils/transform';
|
|
|
|
|
|
export default {
|
|
|
name: 'AudioPlay',
|
|
@@ -30,13 +57,28 @@ export default {
|
|
|
type: String,
|
|
|
default: '',
|
|
|
},
|
|
|
+ showSlider: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ secondFormatConversion,
|
|
|
url: '',
|
|
|
audio: {
|
|
|
paused: true,
|
|
|
+ playing: false,
|
|
|
+ // 音频当前播放时长
|
|
|
+ current_time: 0,
|
|
|
+ // 音频最大播放时长
|
|
|
+ max_time: 0,
|
|
|
+ isPlaying: false,
|
|
|
+ loading: false,
|
|
|
},
|
|
|
+ play_value: 0,
|
|
|
+ audio_allTime: null, // 展示总时间
|
|
|
+ aduio_currentTime: null, // 剩余时间
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
@@ -85,6 +127,50 @@ export default {
|
|
|
}
|
|
|
audio.paused ? audio.play() : audio.pause();
|
|
|
},
|
|
|
+ // 进度条格式化toolTip
|
|
|
+ formatProcessToolTip(index) {
|
|
|
+ let indexs = parseInt((this.audio.max_time / 100) * index);
|
|
|
+ return secondFormatConversion(indexs);
|
|
|
+ },
|
|
|
+ // 点击 拖拽播放音频
|
|
|
+ changeCurrentTime(value) {
|
|
|
+ let audioId = this.fileId;
|
|
|
+ this.$refs[audioId].play();
|
|
|
+ this.audio.playing = true;
|
|
|
+ this.$refs[audioId].currentTime = parseInt((value / 100) * this.audio.max_time);
|
|
|
+ },
|
|
|
+ // 音频加载完之后
|
|
|
+ onLoadedmetadata(res) {
|
|
|
+ this.audio.max_time = parseInt(res.target.duration);
|
|
|
+ this.audio_allTime = secondFormatConversion(this.audio.max_time);
|
|
|
+ },
|
|
|
+ // 当音频当前时间改变后,进度条也要改变
|
|
|
+ onTimeupdate(res) {
|
|
|
+ let audioId = this.fileId;
|
|
|
+ this.audio.current_time = res.target.currentTime;
|
|
|
+ this.play_value = (this.audio.current_time / this.audio.max_time) * 100;
|
|
|
+ if (this.audio.current_time * 1000 > this.ed) {
|
|
|
+ this.$refs[audioId].pause();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onTimeupdateTime(res, playFlag) {
|
|
|
+ if (!res && res !== 0) return;
|
|
|
+ let audioId = this.audioId;
|
|
|
+ this.$refs[audioId].currentTime = res;
|
|
|
+ this.play_value = (res / this.audio.max_time) * 100;
|
|
|
+ if (playFlag) {
|
|
|
+ let audio = document.getElementsByTagName('audio');
|
|
|
+ audio.forEach((item) => {
|
|
|
+ if (item.id !== audioId) {
|
|
|
+ item.pause();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.$refs[audioId].play();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ oncanplaythrough() {
|
|
|
+ this.audio.loading = false;
|
|
|
+ },
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
@@ -93,14 +179,15 @@ export default {
|
|
|
.audio-wrapper {
|
|
|
.audio-play {
|
|
|
display: flex;
|
|
|
+ column-gap: 8px;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- width: 40px;
|
|
|
+ min-width: 40px;
|
|
|
height: 40px;
|
|
|
color: #fff;
|
|
|
cursor: pointer;
|
|
|
background-color: $main-color;
|
|
|
- border-radius: 50%;
|
|
|
+ border-radius: 20px;
|
|
|
|
|
|
&.not-url {
|
|
|
color: #a1a1a1;
|
|
@@ -111,6 +198,37 @@ export default {
|
|
|
width: 20px;
|
|
|
height: 20px;
|
|
|
}
|
|
|
+
|
|
|
+ .audio-time {
|
|
|
+ min-width: 35px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .audio-slider {
|
|
|
+ width: 82px;
|
|
|
+
|
|
|
+ :deep .el-slider__runway {
|
|
|
+ height: 4px;
|
|
|
+ background-color: #1853c6;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep .el-slider__button {
|
|
|
+ width: 4px;
|
|
|
+ height: 4px;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep .el-slider__bar {
|
|
|
+ height: 4px;
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep .el-slider__button-wrapper {
|
|
|
+ top: -16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</style>
|