基于vue.js的音乐播放器

【基于vue.js的音乐播放器】兴趣乃学习的动力,想自己动手写个音乐播放器,查了网上一些博客,最终东拼西凑写了一个。网上有网易云的接口,这里不多赘述了。
整体项目代码挺多的,在这里就只挑选音乐播放和切换音乐来记录了。
https://github.com/gloryin2016/manageplatform
把搜索后获取的音乐列表,将其存入store;通过index来切换不同的歌曲。

基于vue.js的音乐播放器
文章图片
播放器
HTML的audio属性参考 https://www.jianshu.com/p/1fe701c9179f

//进度条直接用的element的slider,修改样式颜色即可

data
data() { return { playing: false, index: 0, // 当前播放歌曲在列表中的下标 currentTime: "00:00", // 当前播放时间 totalTime: "00:00", // 总播放时间 bufferedScaleX: 0, // 缓存进度 processWidth: 0, //播放百分比 progressScaleX: 0, // 播放进度 thumbTranslateX: 0, // 进度条滑块位置 silderBoxX: 0, //进度条滑块位置-->采用element后的 volume: 50, // 音量 error: "", // 报错内容 playType: '1', // 播放类型:1-列表循环,2-随机播放,3-单曲循环 //播放列表 songList: [ { albumId: 75612550, albumTitle: "辞.九门回忆", artistsName: "解忧草", cover: "", finalTime: "04:00", id: 1347524822, index: 6, mvId: 0, name: "辞.九门回忆", sort: "07", url: "https://music.163.com/song/media/outer/url?id=1347524822.mp3", }, { albumId: 85511857, albumTitle: "谪仙", artistsName: "伊格赛听", cover: "", finalTime: "02:0", id: 1421256202, index: 0, mvId: 0, name: "谪仙", sort: "01", url: "https://music.163.com/song/media/outer/url?id=1421256202.mp3", }, { albumId: 35172219, albumTitle: "君の名は - 黄昏之时", artistsName: "Frank_Jiang", cover: "https://p1.music.126.net/YppJiMHyrLc7tDkj6jUttg==/109951162858188597.jpg", finalTime: "03:00", id: 459116892, index: 5, mvId: 0, name: "黄昏之时(FRANKOWO Bootleg)", sort: "06", url: "https://music.163.com/song/media/outer/url?id=459116892.mp3", }, ], //当前播放歌曲 songInfo: { albumId: 75612550, albumTitle: "辞.九门回忆", artistsName: "解忧草/冰幽", cover: "", finalTime: "04:00", id: 1347524822, index: 6, mvId: 0, name: "辞.九门回忆", sort: "07", url: "https://music.163.com/song/media/outer/url?id=1347524822.mp3", }, lyricsObjArr: [],//歌词 lyricIndex: 0,歌词索引 }; },

JS
mounted() { audio = document.getElementById("audio"); this.Init(); }, method: { Init(){ this.songInfo = this.songList[0]; this.audioInit(); } //播放与暂停 play() { if (this.playing) { // 播放中,点击则为暂停 this.playing = false; audio.pause(); } else { // 暂停中,点击则为播放 this.playing = true; audio.play(); } }, audioInit() { let _this = this; let progressL = this.$refs.track.offsetWidth; // 进度条总长 // 播放位置改变时触发[注意:播放和调整指示定位时都会触发](主要事件) audio.addEventListener("timeupdate", () => { // 当前播放时间 _this.currentTime = _this.timeToString(audio.currentTime); let compareTime = audio.currentTime; for (let i = 0; i < _this.lyricsObjArr.length; i++) { if (compareTime > parseInt(_this.lyricsObjArr[i].time)) { const index = _this.$refs.lyric[i].dataset.index; if (i === parseInt(index)) { _this.lyricIndex = i; } } } // 总播放时间 _this.totalTime = _this.timeToString(audio.duration); // 当前播放进度百分比 let precent = audio.currentTime / audio.duration || 0; // 当前播放进度 _this.progressScaleX = precent.toFixed(3); _this.processWidth = precent.toFixed(2) * 100; // 当前缓存进度 // 已缓存时间 let buffered = audio.buffered.length ? audio.buffered.end(audio.buffered.length - 1) : 0; _this.bufferedScaleX = (buffered / audio.duration).toFixed(3); // 当前进度按钮位置 _this.thumbTranslateX = (precent * progressL).toFixed(3); }); // 音频或视频能够不停顿地一直播放 audio.addEventListener("canplaythrough", () => { console.log("canplaythrough"); }); // 音频或视频的时长已改变 audio.addEventListener("durationchange", () => { console.log("durationchange"); _this.totalTime = _this.timeToString(audio.duration); }); // 在音频或视频终止加载时触发,包括终止当前播放(未加载完)进行下一首播放时也会触发 audio.addEventListener("abort", () => { console.log("abort"); }); // 在音频或视频加载发生错误时触发 audio.addEventListener("error", () => { console.log("error"); console.log("-----networkState---------", audio.networkState); console.log("-----readyState---------", audio.readyState); switch (audio.networkState) { case "0": _this.error = "尚未初始化"; break; case "1": _this.error = "正在下载数据"; break; case "3": _this.error = "未找到资源"; break; } audio.readyState == "0" && (_this.error = "音频地址错误"); setTimeout(() => { _this.error = ""; }, 3000); }); // 播放结束 audio.addEventListener( "ended", () => { console.log("ended"); switch (parseInt(_this.playType)) { case 1: // 列表循环 _this.index = _this.index + 1 >= _this.songList.length ? 0 : _this.index + 1; break; case 2: // 随机播放 _this.index = Math.floor(Math.random() * _this.songList.length); break; case 3: // 单曲循环 break; } _this.songInfo = _this.songList[_this.index]; this.$store.dispatch("setSongIndex", _this.index); //在vuex存入当前播放歌曲的index this.GetLyric(_this.songInfo.id); //获取歌词的接口 _this.thumbSlide = true; setTimeout(() => { audio.play(); }, 100); // 解决因为transition的回弹bug setTimeout(() => { _this.thumbSlide = false; }, 1000); }, true ); }, }, // 秒值转字符串 timeToString(param) { param = parseInt(param); let hh = "", mm = "", ss = ""; if (param >= 0 && param < 60) { param < 10 ? (ss = "0" + param) : (ss = param); return "00:" + ss; } else if (param >= 60 && param < 3600) { mm = parseInt(param / 60); mm < 10 ? (mm = "0" + mm) : mm; param - parseInt(mm * 60) < 10 ? (ss = "0" + String(param - parseInt(mm * 60))) : (ss = param - parseInt(mm * 60)); return mm + ":" + ss; } }, //上下首封装 skipFn(type) { switch (parseInt(this.playType)) { case 2: // 随机播放 this.index = Math.floor(Math.random() * this.songList.length); break; default: if (type == "skipBack") { this.index - 1 >= 0 ? this.index-- : 0; } else { this.index = this.index + 1 >= this.songList.length ? this.songList.length - 1 : this.index + 1; } break; } this.songInfo = this.songList[this.index]; this.$store.dispatch("setSongIndex", this.index); this.playing = true; setTimeout(() => { this.totalTime = "00:00"; audio.play(); }, 100); },

    推荐阅读