使用vue制作一个属于自己的音乐播放器

news/2024/11/2 6:29:40/

个人博客原文地址(支持代码预览) 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:00formatTime(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=thisthis.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>

属性

属性描述
autoplayautoplay如果出现该属性,则音频在就绪后马上播放。
controlscontrols如果出现该属性,则向用户显示控件,比如播放按钮。
looploop如果出现该属性,则每当音频结束时重新开始播放。
mutedmuted规定视频输出应该被静音。
preloadpreload如果出现该属性,则音频在页面加载时进行加载,并预备播放。如果使用 “autoplay”,则忽略该属性。
srcurl要播放的音频的 URL。

内容来源—W3School

js创建(本案例使用)

//创建audio,不会在页面中显示。var audio=document.createElement("audio");
//设置src,播放地址。
audio.src ='http://url'

事件

属性描述
oncanplayscript当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。
oncanplaythroughscript当媒介能够无需因缓冲而停止即可播放至结尾时运行的脚本。
onendedscript当媒介已到达结尾时运行的脚本(可发送类似“感谢观看”之类的消息
onpausescript当媒介被用户或程序暂停时运行的脚本。
onplayscript当媒介已就绪可以开始播放时运行的脚本。
onplayingscript当媒介已开始播放时运行的脚本。
onprogressscript当浏览器正在获取媒介数据时运行的脚本。
ontimeupdatescript当播放位置改变时(比如当用户快进到媒介中一个不同的位置时)运行的脚本。

内容来源—W3School

案例准备

格式化时间

// 获取音乐总时长getTime() {let time = this.audio.duration;this.max = time;//总共时长的秒数this.time = this.transTime(time);},// 时间格式化位00:00formatTime(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();},},

http://www.ppmy.cn/news/221929.html

相关文章

HTML5动画图片播放器 高端大气

我们见过很多图片播放插件&#xff08;焦点图&#xff09;&#xff0c;很多都基于jQuery。今天介绍的HTML5图片播放器很特别&#xff0c;它不仅在图片间切换有过渡动画效果&#xff0c;而且在切换时图片中的元素也将出现动画效果&#xff0c;比如图中的文字移动、打散、重新组合…

视频播放器 AVPlayer

{// 设置音频播放AVAudioSession *audioSession [AVAudioSession sharedInstance];[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];//创建播放器CGRect playerFrame CGRectMake(0, 0, _backView.layer.bounds.size.width, _backView.layer.bounds.siz…

android旅游视频播放,VPlayer视频播放器

哔哔&#xff5e; ○讲故事&#xff0c;hhhh一开始很无脑看到QQ(好像)广告能转换身体的看脸时代(先对不起&#xff0c;我奔着看恋爱去的)(鹅鹅鹅&#xff0c;因某些原因就…下架了&#xff0c;这个嘛&#xff0c;却有点可惜&#xff0c;打斗和心理描写蛮可以&#xff0c;也有成…

磁力播放器专辑

软件名称&#xff1a;磁力云 软件版本&#xff1a;v1.2_永久免费 软件语言&#xff1a;中文 软件大小&#xff1a;17M 软件包名&#xff1a;com.ciliyun 支持系统&#xff1a;Android 2.2及更高版本请老司机们文明驾驶&#xff0c;切勿随意飙车 鲨鱼磁力搜索v1.1破解修复最终版…

android 网易视频无法播放器,没错,这就是目前功能最强第三方播放器

我们先前安利的很多视频播放器&#xff0c;因为是个人开发者作品&#xff0c;通常不会要求太多&#xff0c;只要能用够用没广告就很满足了。 但用久了大家可能会感觉不那么舒服&#xff0c;比如软件视觉体验&#xff0c;操作体验跟专业的播放器差距甚远&#xff0c;或者仅仅是简…

【Android】RecycleView简单仿漫画APP图片相关样式

真的真的想不到起什么标题好了&#xff0c;这次的内容真的是太简单了&#xff0c;没有什么挑战性&#xff0c;一天以内就完成了。最近在学kotlin&#xff0c;也会有一份kotlin的代码&#xff0c;鉴于很多人都是从java开始进行android开发的&#xff0c;kotlin的代码就不做一一详…

html钢琴谱播放器,iPad版五线谱播放器《钢琴谱大全》评测

【IT168 评测】钢琴谱大全是由蛐蛐钢琴网开发的一款集五线谱浏览,有声播放,互动播放于一体的五线谱浏览器,自2012年5月4日问世以来,快速受到广大爱好者的追捧,截止发稿,钢琴谱大全,已经荣登苹果中国区免费排行top10,音乐排行top1,以惊人的成绩展示了这款五线谱播放器的…

Python制作音乐播放器

Python用tkinter库制作一个音乐播放器&#xff0c;自定义一个自己想要的播放器。虽然明天其他的播放器强大&#xff0c;如某易云&#xff0c;某狗。但是也是一个好玩的小插件。 1.制作需求 首先要会一点tkinter库的基础使用方法&#xff0c;当然其他gui库也行&#xff01;这里只…