1、原生的audio控件寫法及效果圖:
由于audio
標(biāo)簽原生樣式不能修改UI樣式,所以需要隱藏原生audio
標(biāo)簽,重新寫一個控件進(jìn)行操作audio
2、自定義寫法及效果圖:
代碼實現(xiàn):
先封裝一個組件
audioPlayer.vue
。注意:需提前安裝了Element Plus
<template>
<div>
<audio
@timeupdate="updateProgress"
controls
ref="audioRef"
style="display: none"
>
<source :src="audioUrl" type="audio/mpeg" />
您的瀏覽器不支持音頻播放
</audio>
<div class="audio_right">
<img
v-if="!audioIsPlay"
@click="playAudio"
class="audio_icon"
src="../../../assets/img/play.png"
alt="播放"
/>
<img
v-if="audioIsPlay"
@click="playAudio"
class="audio_icon"
src="../../../assets/img/pause.png"
alt="暫停"
/>
<el-slider
class="slider_box"
v-model="currentProgress"
:show-tooltip="false"
@input="handleProgressChange"
/>
<div class="audio_time">
<span class="audio_current">{{ audioStart }}</span>
/
<span class="audio_total">{{ durationTime }}</span>
</div>
<div class="volume">
<div class="volume_progress" v-show="audioHuds">
<el-slider
vertical
height="100px"
class="volume_bar"
v-model="audioVolume"
:show-tooltip="false"
@change="handleAudioVolume"
/>
</div>
<img
class="volume_icon"
v-if="audioVolume <= 0"
@click.stop="audioHuds = !audioHuds"
src="../../../assets/img/audio_mute.png"
alt=""
/>
<img
class="volume_icon"
v-if="audioVolume > 0"
@click.stop="audioHuds = !audioHuds"
src="../../../assets/img/audio_high.png"
alt=""
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from "vue";
const props = defineProps({
audioUrl: String, //試聽的鏈接
isPauseTtsAudio: Boolean //是否暫停播放試聽
});
const audioIsPlay = ref(true); //音頻是否在播放
const audioStart = ref("0:00");
const durationTime = ref("0:00"); //音頻的總時長,顯示的時間格式
const duration = ref(0); //音頻的總時長
const audioVolume = ref(80); //音量的默認(rèn)值是0.8
const audioHuds = ref(false); //是否顯示音量slider
const audioRef = ref(null);
const currentProgress = ref(0);
watch(() => props.isPauseTtsAudio, (newVal, oldVal) => {
if (newVal) {
// 如果 isPauseTtsAudio 為 true,試聽暫停
handleCloseMusic();
}
});
function handleCloseMusic() {
audioRef.value.pause();
audioIsPlay.value = true;
}
onMounted(() => {
calculateDuration();
});
// 獲取音頻時長
function calculateDuration() {
var myVid = audioRef.value;
myVid.loop = false;
myVid.src = props.audioUrl;
// 監(jiān)聽音頻播放完畢
myVid.addEventListener(
"ended",
function () {
audioIsPlay.value = true;
currentProgress.value = 0;
},
false
);
if (myVid != null) {
myVid.oncanplay = function () {
duration.value = myVid.duration; // 計算音頻時長
durationTime.value = transTime(myVid.duration); //換算成時間格式
};
myVid.volume = 0.8; // 設(shè)置默認(rèn)音量50%
// 進(jìn)入頁面默認(rèn)開始播放
audioRef.value.play();
audioIsPlay.value = false;
}
}
// 音頻播放時間換算
function transTime(duration) {
const minutes = Math.floor(duration / 60);
const seconds = Math.floor(duration % 60);
const formattedMinutes = String(minutes).padStart(2, "0"); //padStart(2,"0") 使用0填充使字符串長度達(dá)到2
const formattedSeconds = String(seconds).padStart(2, "0");
return `${formattedMinutes}:${formattedSeconds}`;
}
// 播放暫??刂?/span>
function playAudio() {
if (audioRef.value.paused) {
audioRef.value.play();
audioIsPlay.value = false;
} else {
audioRef.value.pause();
audioIsPlay.value = true;
}
}
// 根據(jù)當(dāng)前播放時間,實時更新進(jìn)度條
function updateProgress(e) {
var value = e.target.currentTime / e.target.duration;
if (audioRef.value.play) {
currentProgress.value = value * 100;
audioStart.value = transTime(audioRef.value.currentTime);
}
}
//調(diào)整播放進(jìn)度
const handleProgressChange = (val) => {
console.log(val);
if (!val) {
return;
}
let currentTime = duration.value * (val / 100);
// 更新音頻的當(dāng)前播放時間
audioRef.value.currentTime = currentTime;
};
//調(diào)整音量
const handleAudioVolume = (val) => {
audioRef.value.volume = val / 100;
};
</script>
<style lang="scss" scoped>
.audio_right {
width: 230px;
height: 40px;
display: flex;
align-items: center;
background: linear-gradient(to left, #2e7bff 0%, #8ee7ff 100%);
border-radius: 4px;
padding: 0 10px;
box-sizing: border-box;
position: relative;
.slider_box {
width: 160px;
height: 4px;
border-radius: 5px;
background-color: #f1f1f1;
flex: 1;
margin: 0 8px 4px;
}
.audio_icon {
width: 20px;
height: 20px;
margin-bottom: 4px;
cursor: pointer;
}
.audio_time {
color: #f1f1f1;
overflow: hidden;
font-size: 12px;
position: absolute;
bottom: 3px;
left: 80px;
.audio_total {
float: right;
}
.audio_current {
float: left;
}
}
}
.volume {
position: relative;
.volume_progress {
width: 32px;
height: 140px;
position: absolute;
top: -142px;
right: -4px;
}
.volume_bar {
background: #fff;
border-radius: 4px;
}
.volume_icon {
width: 24px;
height: 24px;
cursor: pointer;
}
}
</style>
<style lang="scss">
.el-slider__button-wrapper {
display: flex;
justify-content: center;
align-items: center;
}
.slider_box,
.volume_bar {
.el-slider__button {
width: 8px;
height: 8px;
border: none;
}
.el-slider__bar {
background: #00db15;
}
}
.slider_box {
.el-slider__button-wrapper {
width: 8px;
}
}
.volume_bar {
.el-slider__runway {
margin: 0 14px !important;
}
}
</style>
在父組件內(nèi)引用自定義組件
audioPlayer.vue
文章來源:http://www.zghlxwxcb.cn/news/detail-734900.html
<template>
<AudioPlayer :audioUrl="ttsAudioUrl" :isPauseTtsAudio="isPauseTtsAudio"></AudioPlayer>
</template>
<script setup>
import AudioPlayer from "../components/audioPlayer.vue";
</script>
效果圖:文章來源地址http://www.zghlxwxcb.cn/news/detail-734900.html
到了這里,關(guān)于vue3 + Element Plus自定義音頻audio樣式及控件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!