美文网首页
基于vue.js的音乐播放器

基于vue.js的音乐播放器

作者: 五更月下琉璃 | 来源:发表于2020-09-07 17:17 被阅读0次

    兴趣乃学习的动力,想自己动手写个音乐播放器,查了网上一些博客,最终东拼西凑写了一个。网上有网易云的接口,这里不多赘述了。

    整体项目代码挺多的,在这里就只挑选音乐播放和切换音乐来记录了。
    https://github.com/gloryin2016/manageplatform

    把搜索后获取的音乐列表,将其存入store;通过index来切换不同的歌曲。

    播放器
    HTML的audio属性参考https://www.jianshu.com/p/1fe701c9179f
    //进度条直接用的element的slider,修改样式颜色即可
    <div class="ap-play-track" ref="track">
                <el-slider
                  class="ap-play-track"
                  @change="SetCurrentTime"
                  v-model="processWidth"
                ></el-slider>
    <div>
    <audio :src="songInfo.url" id="audio"></audio>
    

    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);
        },
    

    相关文章

      网友评论

          本文标题:基于vue.js的音乐播放器

          本文链接:https://www.haomeiwen.com/subject/gmllektx.html