以下是包含一个element ui里的el-slider滑块作为音频播放器组件的进度条,其中包括播放/暂停按钮、上一首/下一首按钮、作者信息、音频时长、播放进度条等功能,直接上代码:
<template>
<div class="container">
<div class="middlebox">
<div class="top">
<!-- 播放 -->
<div class="play-box">
<div class="playbtn-box">
<!-- 上一首 -->
<img
class="leftbtn"
@click="nextSong()"
src="@/assets/zuo@2x.png"
alt=""
/>
<!-- 播放 -->
<audio
ref="audio"
id="audio"
autoplay
controls="controls"
style="display: none"
:src="audioSrc"
@pause="onPause"
@play="onPlay"
@timeupdate="handleAudioTimeUpdated"
@loadedmetadata="onLoadedmetadata"
></audio>
<div class="cenbtn" @click="playaudio()">
<img src="@/assets/yuan@2x.png" alt="" />
<div class="btn">
<img
v-if="audio.playing"
class="plays"
@click="onPlay()"
src="@/assets/bofang@2x.png"
alt=""
/>
<img
v-else
class="pauses"
@click="onPause()"
src="@/assets/zanting@2x.png"
alt=""
/>
</div>
</div>
<!-- 下一首 -->
<img
@click="prevSong()"
class="nextbtn"
src="@/assets/you@2x.png"
alt=""
/>
</div>
</div>
<div class="progress-box">
<div class="albumbox">
<h3>第一集</h3>
<div class="author-box">
<h2>作者:天伊</h2>
<h1>
{{ audio.currentTime | formatSecond }}/{{
datas.duration | formatSecond
}}
</h1>
</div>
<!-- 进度条 -->
<div class="progress-bar">
<div class="tab-player-progress">
<el-slider
@change="progressChange"
v-model="audio.currentTime"
:format-tooltip="realFormatSecond"
:max="Number(datas.duration)"
@mouseup.native="mouseupChangeTime"
></el-slider>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
// 将整数转换成 时:分:秒的格式
function realFormatSecond(second) {
var secondType = typeof second;
if (secondType === "number" || secondType === "string") {
second = parseInt(second);
var mimute = Math.floor(second / 60);
second = second - mimute * 60;
return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);
} else {
return "00:00";
}
}
export default {
filters: {
// 将整数转化成时分秒
formatSecond(second = 0) {
return realFormatSecond(second);
},
},
data() {
return {
audioUrl: Common.audioUrl(),
datas: {
fileUrl: "", //音频地址
albumId: "", //专辑id
duration: 0, //时长
},
audio: {
playing: false, // 该字段是音频是否处于播放状态的属性
currentTime: 0, // 音频当前播放时长
},
audioKey: 0,
recordsList: [], //专辑列表
cacheCurrent: 0,
};
},
computed: {
audioSrc() {
let url = this.audioUrl + this.datas.fileUrl;
return url;
},
},
methods: {
// 播放音频
play() {
this.$refs.audio.play();
},
// 暂停音频
pause() {
this.$refs.audio.pause();
},
// 音频播放
onPlay() {
this.audio.playing = true;
},
// 当音频暂停
onPause() {
this.audio.playing = false;
},
// 控制音频的播放与暂停
playaudio() {
return this.audio.playing ? this.pause() : this.play();
},
//获取音频长度
onLoadedmetadata(res) {
this.datas.duration = parseInt(res.target.duration);
},
//进度条触发事件
realFormatSecond(second) {
this.cacheCurrent = second;
return realFormatSecond(second);
},
// 当音频当前时间改变后,进度条也要改变
handleAudioTimeUpdated(res) {
this.audio.currentTime = res.target.currentTime;
// );
},
// 鼠标抬起改变当前时间点
mouseupChangeTime() {
this.progressChange(this.cacheCurrent);
},
// 拖动进度滚动条
progressChange(value) {
this.$refs.audio.currentTime = value >= 0 ? value : this.cacheCurrent;
this.audio.currentTime = value >= 0 ? value : this.cacheCurrent;
},
// 播放上一首歌曲
nextSong() {
this.setPageCounts();
this.pause();
this.audioKey -= 1;
if (this.audioKey < 0) {
this.audioKey = this.recordsList.length - 1;
}
const newArr = this.recordsList.find(
(item, index) => index == this.audioKey
);
this.datas.title = newArr.title;
this.datas.fileUrl = newArr.fileUrl;
this.$nextTick(() => {
this.play();
});
},
// 播放下一首歌曲
prevSong() {
this.pause();
this.audioKey += 1;
if (this.audioKey >= this.recordsList.length) {
this.audioKey = 0;
}
const newArr = this.recordsList.find(
(item, index) => index == this.audioKey
);
this.datas.fileUrl = newArr.fileUrl;
this.$nextTick(() => {
this.play();
});
},
},
};
</script>
<style scoped lang="less">
.middlebox {
width: 880px;
height: 140px;
margin-left: 60px;
.top {
position: relative;
width: 100%;
height: 100%;
margin-top: 70px;
.play-box {
position: absolute;
right: -50px;
display: flex;
justify-content: space-between;
width: 306px;
}
.playbtn-box {
display: flex;
justify-content: center;
align-items: center;
width: 120px;
.cenbtn {
position: relative;
margin: 0 15px;
.plays {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16px;
height: 27px;
}
.pauses {
position: absolute;
top: 50%;
left: 55%;
transform: translate(-50%, -50%);
width: 22px;
height: 26px;
}
}
}
.volume-box {
width: 145px;
display: flex;
justify-content: center;
align-items: center;
.volumImg {
width: 18px;
height: 17px;
}
}
.progress-box {
position: absolute;
left: 0;
bottom: -20px;
display: flex;
justify-content: space-between;
width: 100%;
height: 100px;
.albumImg {
width: 90px;
border-radius: 50%;
margin-right: 15px;
}
.albumbox {
cursor: pointer;
width: 100%;
h3 {
font-size: 18px;
font-weight: 400;
color: #1c1c1c;
margin: 0;
width: 90%;
}
.author-box {
display: flex;
justify-content: space-between;
height: 60px;
h2 {
font-size: 14px;
font-weight: 400;
color: #a4a4a4;
line-height: 40px;
}
h1 {
font-size: 14px;
font-weight: 400;
color: #4a4a4a;
}
}
.progress-bar {
position: relative;
width: 100%;
margin: 0px auto;
text-align: left;
}
.timer {
vertical-align: sub;
font-size: 20px;
font-family: PingFang SC;
font-weight: 500;
color: #b1b1b1;
position: absolute;
left: 20px;
top: 0;
transform: translateY(-50%);
}
.timers {
vertical-align: sub;
font-size: 20px;
font-family: PingFang SC;
font-weight: 500;
color: #b1b1b1;
position: absolute;
right: 20px;
top: 0;
transform: translateY(-50%);
}
// 进度条
.p_slider {
width: 100%;
position: relative;
height: 24px;
display: flex;
align-items: center;
cursor: default;
user-select: none;
outline: none;
}
.p_slider_track {
position: absolute;
height: 5px;
left: 0;
right: 0;
top: 50%;
margin-top: -1px;
background-color: #e6e6e6;
}
.p_slider_fill {
position: absolute;
height: 4px;
width: 100%;
background-color: #ff821e;
left: 0;
top: 50%;
margin-top: -1px;
}
.p-box {
position: relative;
width: 100px;
height: 100px;
margin-top: -100px;
}
.p_slider_thumb {
position: absolute;
top: 100%;
width: 15px;
height: 15px;
background-color: #ff821e;
color: #ff821e;
border-radius: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
}
}
}
}
}
</style>