vue音乐播放器

一般音乐播放器该有的功能基本都有了,只是有些还没有完成,大部分代码 js 或者其他框架也可以用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

功能

1、播放列表
2、切歌
3、暂停/播放
4、歌词显示
5、点击歌词改变进度
6、评论(未完成)
7、收藏歌曲(未完成)
8、滑块改变进度
9、进度条改变进度
10、播放列表
11、播放模式(随机/顺序)
12、播放列表结束提醒
13、播放错误提醒
14、加载/暂停提醒
15、当前播放进度/时间显示
16、侧边小歌词显示
17、缓冲条

部分功能代码

1、解析歌词

把歌词解析成【时间(秒)】+文字的数组
在这里插入图片描述

 jx () {
      var lyrics = this.lrc.split('\n')
      var lrcObj = {}
      for (var i = 0; i < lyrics.length; i++) {
        var lyric = decodeURIComponent(lyrics[i])
        // eslint-disable-next-line no-useless-escape
        var timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/g
        var timeRegExpArr = lyric.match(timeReg)
        if (!timeRegExpArr) continue
        var clause = lyric.replace(timeReg, '')
        for (var k = 0, h = timeRegExpArr.length; k < h; k++) {
          var t = timeRegExpArr[k]
          // eslint-disable-next-line one-var
          var min = Number(String(t.match(/\[\d*/i)).slice(1)),
            // eslint-disable-next-line no-useless-escape
            sec = Number(String(t.match(/\:\d*/i)).slice(1))
          var time = min * 60 + sec
          lrcObj[time] = clause
        }
      }
      return lrcObj
    },
2、打印歌词

把歌词显示到屏幕上并根据播放时间改变歌词大小和颜色

 showlrc () {
      this.$nextTick(() => {
        // 把当前播放时间写入e数组方便比较时间不同来显示歌词
        this.e.push(parseInt(this.currentTime))
        this.i++
        // 判断当前播放时间与前面获取到的歌词时间不一致
        if (this.e[(this.i) - 2] !== parseInt(this.currentTime)) {
          // 获取歌词对应的标签样式
          var x = document.querySelectorAll('#a' + parseInt(this.currentTime))
          this.x.push(x)
          this.a++
          // 判断获取到的当前播放时间的歌词不是空
          if (Array.from(this.x[(this.a)])[0] !== undefined) {
            // 去掉上一句歌词的高光样式
            if (this.r !== 0) {
              this.r[0].style.color = ''
              this.r[0].style.fontSize = ''
            }
            // 当前歌词高光样式
            Array.from(this.x[(this.a)])[0].style.color = 'red'
            Array.from(this.x[(this.a)])[0].style.fontSize = '20px'
            // 打印到侧边小歌词窗口
            this.currentlrc = this.lrc[parseInt(this.currentTime)]
            this.$refs['scroll'].wrap.scrollTop = Array.from(this.x[(this.a)])[0].offsetTop - 270
            this.r = Array.from(this.x[(this.a)])
          }
        }
      })
    },
3、随机/顺序播放

①随机播放:利用 parseInt(a * Math.random()) 生成随机数并根据随机数播放相应的歌曲。
②顺序播放:利用 this.num++ 顺序播放

 // 随机播放
    randomsong () {
      var a = this.songlists.length
      var index = this.num
      while (index === this.num) {
        index = parseInt(a * Math.random())
      }
      this.num = index
      this.getsogdata()
    },
    
 // 播放完成(或者点击下一首)后检查并根据播放模式切歌进行顺序切歌或随机切歌
    playmodel () {
      this.qingkongAll()
      if (!this.randomsongmodel) {
        if (this.num < this.songlists.length) {
          this.getsogdata()
          this.num++
        } else {
          this.$message({
            message: '播放列表中已经没有歌曲了,快去添加心仪的歌曲吧',
            type: 'warning'
          })
          this.num = 0
        }
      } else if (this.randomsongmodel) {
        this.randomsong()
      }
    },
4、改变歌曲进度

在这里插入图片描述

h5代码

<div id="pro-txt"  @mousemove="movestart" @mouseup="moveout">
            <h5 v-if="!ranging">{{songName}}</h5>
            <h5 v-if="ranging && tag">正在加载中...</h5>
            <div id="speed"
                 @mousedown="mousedown"
                 ref="speed" >
                <!-- 缓冲条 -->
                <div id="ranges"  ref="ranges">
                  <img  v-if="tag"
                      @mousemove="movestart"
                      @mousedown="movebegin"
                      draggable="true"
                      class="bar"
                      ref="bar"
                      src="../assets/img/进度条滑块.png" id="bar"
                      >
                  <div id="prograss" ref="prograss"></div>
                </div>
            </div>
            <p id="b">{{time2}}</p>
            <p id="e">{{time}}</p>
        </div>

①拖到滑块改变

// 滑块点击时
    movebegin () {
      this.move = true
      this.clikemove = true
    },
    // 滑块松开时
    moveout () {
      this.move = false
      if (this.clikemove) {
        var audio = document.querySelector('#audio')
        let newPercent = (this.mouseStartX / this.progressLength) * 100
        let a = newPercent * 0.01 * this.lenth
        audio.currentTime = a
      }
      this.clikemove = false
    },
    // 滑块拖拽时
    movestart (e) {
      if (this.move) {
        var left = document.querySelector('#speed')
        this.mouseStartX = e.clientX - left.getBoundingClientRect().left
        this.progressLength = this.$refs.speed.getBoundingClientRect().width
        let newPercent = (this.mouseStartX / this.progressLength) * 100
        if (newPercent <= 100) {
          this.$refs.bar.style.left = newPercent + '%'
          this.$refs.prograss.style.width = newPercent + '%'
        }
        // 拖拽超过100%松开鼠标
        if (newPercent > 100) {
          this.moveout()
        }
      }
    }

②点击进度条改变

// 点击进度条改变进度
    mousedown (e) {
      var audio = document.querySelector('#audio')
      var left = document.querySelector('#speed')
      this.mouseStartX = e.clientX - left.getBoundingClientRect().left
      this.progressLength = this.$refs.speed.getBoundingClientRect().width
      let newPercent = (this.mouseStartX / this.progressLength) * 100
      let a = newPercent * 0.01 * this.lenth
      audio.currentTime = a
    },

③点击歌词改变

// 点击歌词切换进度
    onlrcplay (index) {
      var audio = document.querySelector('#audio')
      audio.currentTime = index
    },
5、显示当前播放时间和总时间

audio标签用到的事件

 <audio ref="audio" id="audio" :src="songUrl"
               @canplaythrough="changeplay"
               @error="playerror"
               @timeupdate="updataTime"
               @loadstart="waiting"
               @ended="playmodel"
               @waiting="waiting"
               @pause="pauseing"
               ></audio>

播放时间 js

// 更新播放时间
    updataTime (e) {
      this.currentTime = e.target.currentTime
      var audio = document.querySelector('#audio')
      const timeRanges = audio.buffered
      if (timeRanges.length !== 0) { var currenRanges = timeRanges.end(timeRanges.length - 1) }
      let min = parseInt(this.currentTime / 60)
      let sec = parseInt(this.currentTime % 60)
      if (min < 10) {
        min = '0' + min
      }
      if (sec < 10) {
        sec = '0' + sec
      }
      if (currenRanges >= this.lenth) { currenRanges = this.lenth }
      this.time2 = min + ':' + sec
      this.time3 = '' + parseFloat(this.currentTime / this.lenth) * 100 + '%'
      var ranges = '' + parseFloat(currenRanges / this.lenth) * 100 + '%'
      // var a = parseInt(this.currentTime / this.lenth * 100)
      if (this.$refs.prograss !== undefined && this.$refs.ranges !== undefined && this.$refs.bar !== undefined && !this.move) {
        // 进度条
        this.$refs.prograss.style.width = this.time3
        // 缓冲条
        this.$refs.ranges.style.width = ranges
        // 进度滑块
        this.$refs.bar.style.left = this.time3
      }
      var re = document.querySelector('#lrcpic')
      // eslint-disable-next-line eqeqeq
      this.showlrc()
      // 控制小歌词旋转动画
      if (re != null && this.playing && this.smalllrcshow) {
        re.style = 'animation-play-state:running'
      }
    },

总时间在获取歌曲信息时已经获取了(在getsongdetail () 里面)

this.time = min + ':' + sec

所有功能代码在项目中基本都注释作用了

完整网站代码 这里

Logo

前往低代码交流专区

更多推荐