<template>
|
<div class="audio-container">
|
<div class="audio_wrap_content">
|
<audio ref="audioRef" @play="playFunc" @pause="pauseFunc" @timeupdate="timeupdateFunc"
|
@loadedmetadata="onLoadedmetadata" @ended="handleEnd">
|
<source :src="audioSrc" />
|
</audio>
|
<div class="cudio_control_content">
|
<el-icon :size="32" color="#3680fa" @click="startPlayOrPause" class="cursor-pointer">
|
<VideoPlay v-show="!audio.playing" />
|
<VideoPause v-show="audio.playing" />
|
</el-icon>
|
<div class="slider">
|
<span>{{ formattedCurrentTime }}</span>
|
<div @mousedown="audio.dragState = true" @mouseup="audio.dragState = false"
|
@mouseleave="audio.dragState = false"><el-slider v-model="sliderTime" size="small" :max="audio.maxTime"
|
:show-tooltip="false" @change="onChange"></el-slider></div>
|
<span>{{ formattedMaxTime }}</span>
|
</div>
|
</div>
|
</div>
|
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, computed, onBeforeUnmount } from 'vue';
|
import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
|
|
const props = defineProps({
|
audioSrc: {
|
type: String,
|
required: true,
|
default: ''
|
}
|
});
|
const sliderTime = ref(0);
|
const audioRef = ref(null);
|
|
const audio = ref({
|
maxTime: 0,
|
currentTime: 0,
|
playing: false,
|
dragState: false
|
});
|
|
|
const formatTime = (second) => {
|
let m = parseInt(second / 60);
|
let s = parseInt(second % 60);
|
let time = "";
|
if (second == 0) {
|
return "0'00''";
|
}
|
if (m == 0) {
|
if (s >= 10) {
|
time = "0'" + s + "''";
|
} else {
|
time = "0'0" + s + "''";
|
}
|
} else {
|
if (s >= 10) {
|
time = m + "'" + s + "''";
|
} else {
|
time = m + "'0" + s + "''";
|
}
|
}
|
return time;
|
};
|
|
const formattedCurrentTime = computed(() => {
|
return formatTime(audio.value.currentTime);
|
});
|
const formattedMaxTime = computed(() => {
|
return formatTime(audio.value.maxTime);
|
});
|
|
const play = () => {
|
audioRef.value.play();
|
};
|
const pause = () => {
|
audioRef.value.pause();
|
};
|
const playFunc = () => {
|
audio.value.playing = true;
|
};
|
const pauseFunc = () => {
|
audio.value.playing = false;
|
};
|
const handleEnd = () => {
|
sliderTime.value = 0;
|
audio.value.playing = false;
|
audio.value.currentTime = 0;
|
};
|
const timeupdateFunc = (res) => {
|
if (!audio.value.dragState) {
|
audio.value.currentTime = res.target.currentTime;
|
sliderTime.value = res.target.currentTime;
|
}
|
};
|
const onLoadedmetadata = (res) => {
|
audio.value.maxTime = parseInt(res.target.duration);
|
};
|
const startPlayOrPause = () => {
|
audio.value.playing ? pause() : play();
|
};
|
const onChange = (value) => {
|
audioRef.value.currentTime = value;
|
};
|
|
onBeforeUnmount(() => {
|
pause();
|
});
|
|
</script>
|
|
<style lang="scss" scoped>
|
.audio-container {
|
width: 400px;
|
border: 1px solid #3680fa;
|
height: 50px;
|
border-radius: 50px;
|
}
|
|
.audio_wrap_content {
|
height: 100%;
|
}
|
|
.cudio_control_content {
|
margin: 0 auto;
|
width: 90%;
|
height: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.slider {
|
flex: 1;
|
width: 100%;
|
display: flex;
|
align-items: center;
|
|
}
|
|
.slider div {
|
flex: 1;
|
}
|
|
.slider span {
|
margin: 0 15px;
|
font-size: 12px;
|
color: rgba(34, 34, 34, 0.5);
|
}
|
|
|
}
|
</style>
|