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

时间:2025-02-21 08:08:54

个人博客原文地址(支持代码预览) /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="/ajax/libs/element-ui/2.13.2/theme-chalk/" rel="stylesheet">
		<script src="/ajax/libs/vue/2.6.11/"></script>
		<script src="/ajax/libs/element-ui/2.13.2/"></script>
		<div >
		            <el-row class="music-row" :class="{isshow:isShow}">
		                <el-col :md="24" class="music">
		                    <!-- <audio  :src=""></audio> -->
		                    <!-- 音乐图片 -->
		
		                    <div class="music-img">
		                        <el-avatar class="music-img" :size="66" shape="square" :src="">
		                            <i class="el-icon-loading"></i>
		                            <!-- <img src="/e/fd/"/> -->
		                        </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="">
		                                                <span>
		                                                    {{ind+1}}
		                                                    <span>{{}}</span>
		                                                </span>
		                                                <span>{{}}</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?-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==-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:///plug/down//212877015.mp3',
										"pic":'/origin/1372100011fb653db9634'
									}, {
										"music_id": "515453363",
										"title": "过客",
										"name": "阿涵",
										"type": "netease",
										"url":'https:///plug/down//109717925.mp3',
										"pic":'/origin/1372100011fb653db9634'
									},
								]
		                    }
		                },
		                methods: {
		                    // 打开和关闭音乐收缩栏
		                    MuBtnClick() {
		                         = !;
		                        (1500);
		                    },
		                    hidden(time) {
		                        if ( == false) {
		                             = setTimeout(() => {
		                                 = true;
		                            }, time);
		                        } else {
		                            clearTimeout();
		                             = false;
		                        }
		                    },
		                    // 播放暂停
		                    pause() {
		                        if ( !== null && ) {
		                             = true;
		                            if () {
		                                (); // 播放
		                                 = true;
		                            } else {
		                                (); // 暂停
		                                 = false;
		                                ("暂停被调用了");
		                            }
		                        } else {
		                            this.$message({
		                                showClose: true,
		                                message: "音乐还没有加载成功呢!",
		                                type: "warning",
		                            });
		                        }
		                    },
		                    // 快进音乐
		                    getVal() {
		                        if (! ||  != 0) {
		                             = ;
		                            if ( == ()) {
		                                ();
		                                 = false;
		                            }
		                        }
		                    },
		                    // 获取音乐总时长
		                    getTime() {
		                        let time = ;
		                         = time;
		                        //总共时长的秒数
		                         = (time);
		                    },
		                    // 时间格式化位00:00
		                    formatTime(value) {
		                        let time = "";
		                        let s = (":");
		                        let i = 0;
		                        for (; i <  - 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 = (h + ":" + m + ":" + s);
		                        } else {
		                            time = (m + ":" + s);
		                        }
		                        return time;
		                    },
		                    getMusic() {
		                        if (![].pause) {
		                             = []
		                             = [].url;
		                            // ("获取音乐");
		                            // const qs = require("qs");
		                            // let that = this;
		                            // ([].type);
		                            // this.$post(
		                            //         "/music",
		                            //         ({
		                            //             input: [].music_id,
		                            //             filter: "id",
		                            //             type: [].type,
		                            //             page: 1,
		                            //         })
		                            //     )
		                            //     .then(function(res) {
		                            //          = [0];
		                            //          = ;
		                            //     })
		                            //     .catch(function(error) {
		                            //         (); // 暂停
		                            //          = false;
		                            //     });
		                        } else {
		                            ();
		                             = {
		                                title: [].title,
		                                author: [].name,
		                                pic: [].img,
		                                url: [].url,
		                            };
		                             = [].url;
		                        }
		                    },
		                    // 获取我的音乐列表
		                    getList() {
		                         = (() * );
		                         = ;
		                        ();
		                        // let that = this;
		                        // this.$get("url")
		                        //   .then(function (res) {
		                        //      = ;
		                        //      = (() * );
		                        //      = ;
		                        //     ();
		                        //   })
		                        //   .catch(function (error) {});
		                    },
							mError() {
							      if () {
							        ("出错");
							        this.$message({
							          showClose: true,
							          message: "播放错误,自动播放下一首",
							          type: "error",
							        });
							        if ([].musicInfo) {
							          delete [].musicInfo;
							        }
							         =  ==  - 1 ? 0 :  + 1;
							      }
							    },
							    mCanplay() {
							       = true;
							      if () {
							        (); // 播放
							         = true;
							      }
							      ();
							    },
							    mTimeUpdate() {
							       = ;
							       = ();
							    },
							    mEnded() {
							      if ( == 0) {
							        (); // 暂停
							         = false;
							      } else if ( == 1) {
							        (); // 播放
							         = true;
							      } else {
							         =  ==  - 1 ? 0 :  + 1;
							      }
							    },
		                },
		                mounted() {
		                    (5000);
		                    let that = this;
		                },
		                 created() {
		                   // =('music')
		                    = ("audio");
		                   ();
		                   let that = this;
		                   ("canplay", , false),
		                   ("timeupdate", , false);
		                   ("ended", , false);
		                   ("error", , false);
		                 },
						  beforeDestroy() {
						     let that=this
						     ("canplay", );
						     ("ended", );
						     ("error", );
						     ("timeupdate", );
						   },
		                watch: {
		                    index(val) {
		                        if () {
		                            (); // 播放
		                             = true;
		                        }
		                         = false;
		                         = 0;
		                        // ();
		                         = "";
		                        ();
		                    },
		                },
		            }
		            var Ctor = (Main)
		            new Ctor().$mount(('app'))
		        </script>

了解audio

html标签

<audio src="http:///plug/down//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 = ;
       = time;
      //总共时长的秒数
       = (time);
    },
    // 时间格式化位00:00
    formatTime(value) {
      let time = "";
      let s = (":");
      let i = 0;
      for (; i <  - 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 = (h + ":" + m + ":" + s);
      } else {
        time = (m + ":" + s);
      }
      return time;
    },

创建及绑定事件

created() {
    // 创建Audio	
     = ("audio");
    ();
    let that = this;
    // 当音乐准备就绪时的操作
    (
      "canplay",
      function () {
        ("加载成功");
        ();
         = true;
	//防止自动播放
        if () {
          (); // 播放
           = true;
        }
        ();
        // ()
      },
      false
    ),
//快进时的操作,同步时间
      (
        "timeupdate",
        function () {
           = ;
           = ();
        },
        false
      );
//当音乐播放到结束后的操作,
    (
      "ended",
      function () {
        if ( == 0) {
          (); // 暂停
           = false;
        } else if ( == 1) {
          (); // 播放
           = true;
        } else {
             ==  - 1 ? 0 :  + 1;
        }
      },
      false
    );
  },

播放暂停、快进

// 播放暂停
    pause() {
      if ( !== null && ) {
         = true;
        if () {
          (); // 播放
           = true;
        } else {
          (); // 暂停
           = false;
          ("暂停被调用了");
        }
      } else {
        this.$message({
          showClose: true,
          message: "音乐还没有加载成功呢!",
          type: "warning",
        });
      }
    },
    // 快进音乐
    getVal() {
      if (! ||  != 0) {
         = ;
        if ( == ()) {
          ();
           = false;
        }
      }
    },

切换

主要时通过监听器,监听音乐id的变化来切换歌曲

 watch: {
    index(val) {
      if () {
        (); // 播放
         = true;
      }
       = false;
       = 0;
      // ();
       = "";
      ();
    },
  },