最近公司翻新项目,里面有个播放录音的功能跟系统上的音乐播放器功能一样,在网上找了好多帖子没找到,基本都是手撸网易云,就手写了一个。
<template>
<div class="audio-player">
<el-row gutter="24">
<audio style="opacity: 0;position: absolute;z-index: -1;" ref="audio" :src="audioSrc" @canplay="onCanPlay"
@timeupdate="onTimeUpdate" @loadedmetadata="onLoadedMetadata" controls></audio>
<el-col :xs="24">
<el-card>
<!-- 歌曲名 -->
<div class="music-name">{{ audioSrc }}</div>
<!-- 播放组件 -->
<div class="player-controls">
<el-button @click="prev" :disabled="ind == 0">上一首</el-button>
<el-button @click="playPause">{{ isPlaying ? '暂停' : '播放' }}</el-button>
<el-button @click="nextM" :disabled="ind == music.length - 1">下一首</el-button>
<div class="progress-bar">
<input type="range" min="0" max="100" v-model="progress" @input="setProgress" class="progress-bar-inp">
<span class="progress-bar-time">{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</span>
</div>
<el-button @click="isCirculate">
{{ circulate ? '关闭单曲循环' : '单曲循环' }}
</el-button>
</div>
</el-card>
</el-col>
<el-col :xs="24">
<el-table :data="music" style="width: 100%;">
<el-table-column width="80px" prop="name" label="姓名"></el-table-column>
<el-table-column width="80px" prop="form" label="通话方向"></el-table-column>
<el-table-column width="80px" prop="time" label="通话时间"></el-table-column>
<el-table-column prop="url" label="通话内容" ></el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
// Define music list
const music = [
{ name: '歌曲2',form:'拨入',time:'02:58', url: 'https://www.ihaoge.net/server/1/405517298.mp3' },
{ name: '歌曲3',form:'拨入',time:'04:54', url: 'https://www.ihaoge.net/server/1/405342362.mp3' },
{ name: '歌曲4',form:'拨出',time:'03:23', url: 'https://www.ihaoge.net/server/1/405078016.mp3' }
];
const audioSrc = ref(music[0].url);
const audio = ref(null);
const currentTime = ref(0);
const duration = ref(0);
const progress = ref(0);
const isPlaying = ref(false);
const ind = ref(0);
const circulate = ref(false);
// 根据音频的当前时间更新进度
const onTimeUpdate = () => {
currentTime.value = audio.value.currentTime;
progress.value = (currentTime.value / duration.value) * 100;
};
// 加载放时间
const onLoadedMetadata = () => {
duration.value = audio.value.duration;
};
// 初始化音频
const onCanPlay = () => {
duration.value = audio.value.duration;
};
// 暂停、播放按钮
const playPause = () => {
if (isPlaying.value) {
audio.value.pause();
} else {
audio.value.play();
}
isPlaying.value = !isPlaying.value;
};
// 歌曲时间处理
const setProgress = () => {
audio.value.currentTime = (progress.value / 100) * duration.value;
};
// 上一曲
const prev = () => {
ind.value--;
audioSrc.value = music[ind.value].url;
loadMusic();
};
// 下一曲
const nextM = () => {
ind.value++;
audioSrc.value = music[ind.value].url;
loadMusic();
};
// 加载播放音乐
const loadMusic = () => {
isPlaying.value = false;
setTimeout(() => {
audio.value.play();
isPlaying.value = true;
}, 500);
};
// 单曲循环
const isCirculate = () => {
circulate.value = !circulate.value
}
// 音乐时间实时转换
const formatTime = (time) => {
if (!isNaN(time)) {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}
return '00:00';
};
// 监听播放时间并修改进度条进度
watch([currentTime, duration], () => {
progress.value = (currentTime.value / duration.value) * 100;
if (progress.value == 100) {
if (ind.value < music.length - 1) {
if (circulate) {
ind.value++;
}
audioSrc.value = music[ind.value].url;
loadMusic();
} else {//当前列表无音乐暂停播放
isPlaying.value = false;
progress.value = 0
}
}
});
</script>
<style lang="scss" scoped>
.audio-player{
}
.music-name {
width: 100%;
height: 32px;
line-height: 32px;
text-align: center;
}
.player-controls {
width: 100%;
display: flex;
justify-content: space-around;
.progress-bar {
display: flex;
flex:1;
.progress-bar-inp {
flex: 1;
}
.progress-bar-time {
width: 90px;
height: 32px;
line-height: 32px;
display: flex;
justify-content: center;
}
}
}
.list-item {
display: flex;
justify-content: space-between;
}
</style>