基于vue.js的音乐播放器

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

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

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

基于vue.js的音乐播放器_第1张图片
播放器

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

你可能感兴趣的:(基于vue.js的音乐播放器)