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

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

属性

属性描述
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: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();
    },
  },
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值