使用vue制作一个属于自己的音乐播放器
前言其中在想在博客中添加音乐播放功能的时候,也考虑也其它音乐播放器插件如APlayer,页面和功能都能满足要求。而且播放页面也很好看,功能几乎都有。但是我不需要那么多功能,所以我自己尝试制作一个属于自己博客的音乐播放器。页面布局及样式参考APlayer案例预览<style>.isshow {left: -66px !important;}.music-row {height: 66px
·
个人博客原文地址(支持代码预览) https://gitee.com/baymaxsjj
前言
其中在想在博客中添加音乐播放功能的时候,也考虑也其它音乐播放器插件如APlayer,页面和功能都能满足要求。而且播放页面也很好看,功能几乎都有。但是我不需要那么多功能,所以我自己尝试制作一个属于自己博客的音乐播放器。页面布局及样式参考APlayer
案例预览(点击预览云墨白-音乐播放器)
<style>
.isshow {
left: -66px !important;
}
.music-row {
height: 66px;
bottom: 0px;
left: 0;
z-index: 999;
transition: all 0.5s;
margin-top: 60px;
}
.music-row:hover {
left: 0px !important;
}
.music-row .music {
transition: all 0.3s;
display: flex;
justify-content: left;
}
.music-row .music .music-img {
position: relative;
height: 66px;
width: 66px;
cursor: pointer;
}
.music-row .music .music-img:hover .music-toggle {
color: var(--main-5);
font-size: 25px;
}
.music-row .music .music-img .music-toggle {
width: 30px;
height: 30px;
font-size: 20px;
color: var(--main-6);
text-align: center;
line-height: 30px;
position: absolute;
bottom: 50%;
right: 50%;
transform: translate(50%,50%);
transition: all 0.3s;
}
.music-row .music .music-img .music-toggle:hover {
color: var(--main-5);
}
.music-row .music .music-img .musicActive {
bottom: 0px;
right: 0px;
transform: translate(0%,0%);
}
.music-row .music .music-content {
width: 334px;
height: 66px;
border-top: 1px solid #e9e9e9;
padding: 3px 5px;
background-color: #fff;
box-sizing: border-box;
position: relative;
display: flex;
flex-wrap: wrap;
}
.music-row .music .music-content .music-list {
width: 100%;
height: 100px;
background-color: #fff;
position: absolute;
top: -100px;
left: 0;
margin: 0;
padding: 5px;
overflow: auto;
box-sizing: border-box;
border-bottom: 1px solid #ccc;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.music-row .music .music-content .music-list li {
height: 30px;
line-height: 30px;
font-size: 14px;
padding: 0 4px;
margin: 2px 0;
color: var(--main-6);
background-color: #f8f9f9;
transition: all 0.3s;
cursor: pointer;
display: flex;
justify-content: space-between;
}
.music-row .music .music-content .music-list li span {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.music-row .music .music-content .active {
color: #f56c6c !important;
border-left: 3px solid #f56c6c;
}
.music-row .music .music-content .cont-top {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 15px;
width: 65%;
height: 40px;
line-height: 40px;
}
.music-row .music .music-content .cont-cont {
position: absolute;
top: 3px;
right: 0;
}
.music-row .music .music-content .cont-cont .cont-itme {
display: inline-block;
width: 30px;
height: 40px;
text-align: center;
line-height: 40px;
font-size: 18px;
transition: all 0.2s;
}
.music-row .music .music-content .cont-cont .cont-itme:hover {
cursor: pointer;
color: #ccc;
}
.music-row .music .music-content .cont-bottom {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 28px;
display: flex;
justify-content: left;
padding: 0 5px;
box-sizing: border-box;
}
.music-row .music .music-content .cont-bottom .bottom-progress {
width: 80%;
display: flex;
align-items: center;
}
.music-row .music .music-content .cont-bottom .time {
font-size: 12px;
}
.music-row .music .music-content .cont-bottom .music-func {
line-height: 28px;
}
.music-row .music .music-content .cont-bottom .music-func span {
margin: 0 3px;
cursor: pointer;
}
.music-row .music .music-btn {
height: 66px;
width: 18px;
background-color: #ccc;
cursor: pointer;
line-height: 66px;
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
}
</style>
<link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.13.2/theme-chalk/index.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.13.2/index.js"></script>
<div id="app">
<el-row class="music-row" :class="{isshow:isShow}">
<el-col :md="24" class="music">
<!-- <audio id="music" :src="musicInfo.url"></audio> -->
<!-- 音乐图片 -->
<div class="music-img">
<el-avatar class="music-img" :size="66" shape="square" :src="musicInfo.pic">
<i class="el-icon-loading"></i>
<!-- <img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/> -->
</el-avatar>
<span :class="{musicActive:isPlay}" @click="pause" class="iconfont music-toggle"><span :class="isPlay?'el-icon-video-pause':'el-icon-video-play'"></span>
</span></div>
<!-- 展开模块 -->
<transition name="el-zoom-in-center">
<div v-show="muIsShow" class="music-content">
<transition name="el-zoom-in-bottom">
<!-- 音乐列表模块 -->
<div v-show="isList" class="music-list scrollbar">
<el-scrollbar style="width: 100%;
height: 100%;">
<ul style="padding:0">
<li :class="{active:index==ind}" @click="index=ind" v-for="(item,ind) of musics" :key="item.musicId">
<span>
{{ind+1}}
<span>{{item.title}}</span>
</span>
<span>{{item.name}}</span>
</li>
</ul>
</el-scrollbar>
</div>
</transition>
<!-- 标题 作者 -->
<div class="cont-top">
<span>{{musics[index].title}}</span>
<span>---</span>
<span>{{musics[index].name}}</span>
</div>
<!--暂停 快进 -->
<div class="cont-cont">
<span class="cont-itme el-icon-d-arrow-left" @click="index=index==0?musics.length-1:index-1"></span>
<span @click="pause" class="cont-itme iconfont" :class="isPlay?'el-icon-video-pause':'el-icon-video-play'"></span>
<span class="cont-itme el-icon-d-arrow-right" @click="index=index==musics.length-1?0:index+1"></span>
<span class="cont-itme el-icon-menu" @click="isList=!isList"></span>
</div>
<!-- 音乐拖动条 时间 -->
<div class="cont-bottom">
<div class="bottom-progress">
<el-slider style="width:80%" tooltip-class="content-bg8" :format-tooltip="transTime" @change="getVal()" input-size="mini" :min="0" :max="max" v-model="numb"></el-slider>
<!-- <input class="bottom-range" v-model="numb" type="range" min="0" :max="max" @input="getVal()" :style="{background: '-webkit-linear-gradient(top, var(--main-5), var(--main-5)) 0% 0% / '+ numb*100/max +'% 100% no-repeat'}"/> -->
<span class="time" style="padding-left:10px">{{newTime}}</span>
<span class="time">/</span>
<span class="time">{{time}}</span>
</div>
<!-- 循环播放 -->
<div class="music-func">
<span @click="cycle=cycle==2?0:cycle+1" class="cont-itme iconfont" :class="cycle==0?'el-icon-finished':cycle==1?'el-icon-refresh':'el-icon-sort'"></span>
</div>
</div>
</div>
</transition>
<!-- 扩展栏 -->
<div class="music-btn" @click="MuBtnClick">
<i :class="muIsShow?'el-icon-arrow-left':'el-icon-arrow-right'"></i>
</div>
</el-col>
</el-row>
</div>
<script>
var Main = {
data() {
return {
index: 0, //播放列表
muIsShow: false, //是否显示
isPlay: false, //是否播放
canplay: false, //是否能播放
loading: false, //是否自动播放
cycle: 0,
numb: 0,
time: "00:00",
newTime: "00:00",
max: 0,
audio: "",
musicInfo: {},
isList: false,
isShow: false,
setTimeout: null,
musics: [
{
"music_id": "1463165983",
"title": "最美的期待",
"name": "周笔畅",
"type": "netease",
"url":'https://www.0dutv.com/plug/down/up2.php/212877015.mp3',
"pic":'https://p.pstatp.com/origin/1372100011fb653db9634'
}, {
"music_id": "515453363",
"title": "过客",
"name": "阿涵",
"type": "netease",
"url":'https://www.0dutv.com/plug/down/up2.php/109717925.mp3',
"pic":'https://p.pstatp.com/origin/1372100011fb653db9634'
},
]
}
},
methods: {
// 打开和关闭音乐收缩栏
MuBtnClick() {
this.muIsShow = !this.muIsShow;
this.hidden(1500);
},
hidden(time) {
if (this.muIsShow == false) {
this.setTimeout = setTimeout(() => {
this.isShow = true;
}, time);
} else {
clearTimeout(this.setTimeout);
this.isShow = false;
}
},
// 播放暂停
pause() {
if (this.audio !== null && this.canplay) {
this.loading = true;
if (this.audio.paused) {
this.audio.play(); // 播放
this.isPlay = true;
} else {
this.audio.pause(); // 暂停
this.isPlay = false;
console.log("暂停被调用了");
}
} else {
this.$message({
showClose: true,
message: "音乐还没有加载成功呢!",
type: "warning",
});
}
},
// 快进音乐
getVal() {
if (!this.audio.paused || this.audio.currentTime != 0) {
this.audio.currentTime = this.numb;
if (this.numb == Math.floor(this.max)) {
this.audio.pause();
this.isPlay = false;
}
}
},
// 获取音乐总时长
getTime() {
let time = this.audio.duration;
this.max = time;
//总共时长的秒数
this.time = this.transTime(time);
},
// 时间格式化位00:00
formatTime(value) {
let time = "";
let s = value.split(":");
let i = 0;
for (; i < s.length - 1; i++) {
time += s[i].length == 1 ? "0" + s[i] : s[i];
time += ":";
}
time += s[i].length == 1 ? "0" + s[i] : s[i];
return time;
},
// 把毫秒变成时分秒
transTime(value) {
let time = "";
let h = parseInt(value / 3600);
value %= 3600;
let m = parseInt(value / 60);
let s = parseInt(value % 60);
if (h > 0) {
time = this.formatTime(h + ":" + m + ":" + s);
} else {
time = this.formatTime(m + ":" + s);
}
return time;
},
getMusic() {
if (!this.musics[this.index].pause) {
this.musicInfo = this.musics[this.index]
this.audio.src = this.musics[this.index].url;
// console.log("获取音乐");
// const qs = require("qs");
// let that = this;
// console.log(that.musics[that.index].type);
// this.$post(
// "/music",
// qs.stringify({
// input: that.musics[that.index].music_id,
// filter: "id",
// type: that.musics[that.index].type,
// page: 1,
// })
// )
// .then(function(res) {
// that.musicInfo = res.data[0];
// that.audio.src = that.musicInfo.url;
// })
// .catch(function(error) {
// that.audio.pause(); // 暂停
// that.isPlay = false;
// });
} else {
console.log(this.index);
this.musicInfo = {
title: this.musics[this.index].title,
author: this.musics[this.index].name,
pic: this.musics[this.index].img,
url: this.musics[this.index].url,
};
this.audio.src = this.musics[this.index].url;
}
},
// 获取我的音乐列表
getList() {
this.index = Math.floor(Math.random() * this.musics.length);
this.length = this.musics.length;
this.getMusic();
// let that = this;
// this.$get("url")
// .then(function (res) {
// that.musics = res.data;
// that.index = Math.floor(Math.random() * that.musics.length);
// that.length = that.musics.length;
// that.getMusic();
// })
// .catch(function (error) {});
},
mError() {
if (this.loading) {
console.log("出错");
this.$message({
showClose: true,
message: "播放错误,自动播放下一首",
type: "error",
});
if (this.musics[this.index].musicInfo) {
delete this.musics[this.index].musicInfo;
}
this.index = this.index == this.musics.length - 1 ? 0 : this.index + 1;
}
},
mCanplay() {
this.canplay = true;
if (this.loading) {
this.audio.play(); // 播放
this.isPlay = true;
}
this.getTime();
},
mTimeUpdate() {
this.numb = this.audio.currentTime;
this.newTime = this.transTime(this.audio.currentTime);
},
mEnded() {
if (this.cycle == 0) {
this.audio.pause(); // 暂停
this.isPlay = false;
} else if (this.cycle == 1) {
this.audio.play(); // 播放
this.isPlay = true;
} else {
this.index = this.index == this.musics.length - 1 ? 0 : this.index + 1;
}
},
},
mounted() {
this.hidden(5000);
let that = this;
},
created() {
// this.audio=document.getElementById('music')
this.audio = document.createElement("audio");
this.getList();
let that = this;
this.audio.addEventListener("canplay", that.mCanplay, false),
this.audio.addEventListener("timeupdate", that.mTimeUpdate, false);
this.audio.addEventListener("ended", that.mEnded, false);
this.audio.addEventListener("error", that.mError, false);
},
beforeDestroy() {
let that=this
this.audio.removeEventListener("canplay", that.mCanplay);
this.audio.removeEventListener("ended", that.mEnded);
this.audio.removeEventListener("error", that.mError);
this.audio.removeEventListener("timeupdate", that.mTimeUpdate);
},
watch: {
index(val) {
if (this.loading) {
this.audio.play(); // 播放
this.isPlay = true;
}
this.canplay = false;
this.audio.currentTime = 0;
// this.audio.pause();
this.audio.src = "";
this.getMusic();
},
},
}
var Ctor = Vue.extend(Main)
new Ctor().$mount(document.getElementById('app'))
</script>
了解audio
html标签
<audio src="http://www.0dutv.com/plug/down/up2.php/109717925.mp3" controls="controls">
Your browser does not support the audio element.
</audio>
属性
属性 | 值 | 描述 |
---|---|---|
autoplay | autoplay | 如果出现该属性,则音频在就绪后马上播放。 |
controls | controls | 如果出现该属性,则向用户显示控件,比如播放按钮。 |
loop | loop | 如果出现该属性,则每当音频结束时重新开始播放。 |
muted | muted | 规定视频输出应该被静音。 |
preload | preload | 如果出现该属性,则音频在页面加载时进行加载,并预备播放。如果使用 “autoplay”,则忽略该属性。 |
src | url | 要播放的音频的 URL。 |
内容来源—W3School
js创建(本案例使用)
//创建audio,不会在页面中显示。
var audio=document.createElement("audio");
//设置src,播放地址。
audio.src ='http://url'
事件
属性 | 值 | 描述 |
---|---|---|
oncanplay | script | 当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。 |
oncanplaythrough | script | 当媒介能够无需因缓冲而停止即可播放至结尾时运行的脚本。 |
onended | script | 当媒介已到达结尾时运行的脚本(可发送类似“感谢观看”之类的消息 |
onpause | script | 当媒介被用户或程序暂停时运行的脚本。 |
onplay | script | 当媒介已就绪可以开始播放时运行的脚本。 |
onplaying | script | 当媒介已开始播放时运行的脚本。 |
onprogress | script | 当浏览器正在获取媒介数据时运行的脚本。 |
ontimeupdate | script | 当播放位置改变时(比如当用户快进到媒介中一个不同的位置时)运行的脚本。 |
内容来源—W3School
案例准备
格式化时间
// 获取音乐总时长
getTime() {
let time = this.audio.duration;
this.max = time;
//总共时长的秒数
this.time = this.transTime(time);
},
// 时间格式化位00:00
formatTime(value) {
let time = "";
let s = value.split(":");
let i = 0;
for (; i < s.length - 1; i++) {
time += s[i].length == 1 ? "0" + s[i] : s[i];
time += ":";
}
time += s[i].length == 1 ? "0" + s[i] : s[i];
return time;
},
// 把毫秒变成时分秒
transTime(value) {
let time = "";
let h = parseInt(value / 3600);
value %= 3600;
let m = parseInt(value / 60);
let s = parseInt(value % 60);
if (h > 0) {
time = this.formatTime(h + ":" + m + ":" + s);
} else {
time = this.formatTime(m + ":" + s);
}
return time;
},
创建及绑定事件
created() {
// 创建Audio
this.audio = document.createElement("audio");
this.getList();
let that = this;
// 当音乐准备就绪时的操作
this.audio.addEventListener(
"canplay",
function () {
console.log("加载成功");
console.log(that.musicInfo.url);
that.canplay = true;
//防止自动播放
if (that.loading) {
that.audio.play(); // 播放
that.isPlay = true;
}
that.getTime();
// that.pause()
},
false
),
//快进时的操作,同步时间
this.audio.addEventListener(
"timeupdate",
function () {
that.numb = that.audio.currentTime;
that.newTime = that.transTime(that.audio.currentTime);
},
false
);
//当音乐播放到结束后的操作,
this.audio.addEventListener(
"ended",
function () {
if (that.cycle == 0) {
that.audio.pause(); // 暂停
that.isPlay = false;
} else if (that.cycle == 1) {
that.audio.play(); // 播放
that.isPlay = true;
} else {
that.index == that.musics.length - 1 ? 0 : that.index + 1;
}
},
false
);
},
播放暂停、快进
// 播放暂停
pause() {
if (this.audio !== null && this.canplay) {
this.loading = true;
if (this.audio.paused) {
this.audio.play(); // 播放
this.isPlay = true;
} else {
this.audio.pause(); // 暂停
this.isPlay = false;
console.log("暂停被调用了");
}
} else {
this.$message({
showClose: true,
message: "音乐还没有加载成功呢!",
type: "warning",
});
}
},
// 快进音乐
getVal() {
if (!this.audio.paused || this.audio.currentTime != 0) {
this.audio.currentTime = this.numb;
if (this.numb == Math.floor(this.max)) {
this.audio.pause();
this.isPlay = false;
}
}
},
切换
主要时通过监听器,监听音乐id的变化来切换歌曲
watch: {
index(val) {
if (this.loading) {
this.audio.play(); // 播放
this.isPlay = true;
}
this.canplay = false;
this.audio.currentTime = 0;
// this.audio.pause();
this.audio.src = "";
this.getMusic();
},
},
更多推荐
已为社区贡献1条内容
所有评论(0)