• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

微信小程序音乐播放

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  最近在写一个艾美食艾音乐的微信小程序,其中有用到音乐播放的功能,基本播放切换功能已经实现,但是在反复切换歌曲、重新进入歌曲以及单曲循环、列表循环的测试过程中还是发生了bug,特此写一篇文章,捋一下思路.(功能写到后面小程序官方文档将音频这一块全都更新了...)

  坑点:由于小程序主体部分没有app.wxml,这就导致小程序不能写一些公共的页面结构,如果有相同的部分,只能封装成组件再引入.

  在我们点击歌曲列表中的某首歌的时候,会进入音乐播放界面,当我们退出音乐播放界面,歌曲仍然继续播放,但此时由于退出当前路由,页面data中的数据也已被销毁,当我们再次进入播放界面相当于重新进行页面加载,所以需要我们进行分情况判断,播放歌曲变的较为复杂.

  一.存放公共数据

    在我们进入音乐播放界面之前要存一下:

      当前专辑信息:album(Object)

      当前播放列表:playList(Array)

      当前播放歌曲的index:playIndex(Number)

      播放模式:mode(String)

      封面旋转的角度:imgRotate(Number)

   

// app.js
globalData: { album: null,
// 当前专辑信息 playList: [], // 当前播放列表 playIndex: 0, // 当前播放歌曲index mode: \'multiple\', // 循环模式 multiple: 循环播放, single: 单曲循环 imgRotate: 0, // 封面旋转角度
}

 

  二.专辑列表

    在专辑列表中点击某个专辑,进入该专辑的歌曲列表,同时将 该专辑的信息 存入globalData.

// music.js
gotoSongList(e) { let item
= e.currentTarget.dataset.type app.globalData.album = item // 将专辑信息存入globalData wx.navigateTo({ url: \'../songlist/songlist\' }) }

  三.歌曲列表

    在歌曲列表中点击播放某首歌时,进入歌曲播放界面,同时将 该专辑的歌曲列表、当前播放歌曲的index 存入globalData.

// songlist.js
// 播放歌曲
  play(e) {
    app.globalData.playList = this.data.songList
    let index = e.currentTarget.dataset.index
    app.globalData.playIndex = index
    let url = \'../player/player\'
    wx.navigateTo({
      url: url
    })
}

  四.歌曲播放页面

    需要在data中存放一下信息:

      当前歌曲信息:item(Object)

      歌曲解析后的歌词:parseLyric(String)

      当前播放进度点的歌词:lineLyric(String)

      播放模式:mode(String)

      封面旋转的角度:imgRotate(Number)

      进度条的值:SliderValue(Number)

      音频的长度:duration(Number)

      音频的播放位置:currentPosition(Number)

      播放状态:playStatus(Boolean)

const app = getApp();
var Base64 = require(\'../../utils/base64.js\').Base64
var Lyric = require(\'../../utils/lyric-parse.js\')
Page({
  data: {
    item: {}, // 当前歌曲信息
    parseLyric: \'\', // 歌曲解析后的歌词
    lineLyric: \'\', // 当前播放进度点的歌词
    mode: \'\', // 播放模式
    imgRotate: 0, // 封面旋转的角度
    sliderValue: 0, // 进度条的值
    duration: 0, // 音频的长度(单位:s)
    currentPosition: 0, // 音频的播放位置(单位:s)
    playStatus: 0, // 播放状态
    timee: 0, // 定时器 根据歌曲进度改变slider进度
    coverImg: \'\', // 封面图片
    isDel: false, // 当前列表是否只有一首歌曲
  },
  onLoad() {
    let item = app.globalData.playList[app.globalData.playIndex]
    let album = app.globalData.album
    // 获取背景音频信息
    const backgroundAudioManager = wx.getBackgroundAudioManager()
    console.log(backgroundAudioManager, \'backgroundAudioManager\')
    if (backgroundAudioManager.src == item.src) { // 继续听歌
      console.log(\'继续听歌\')
    } else { // 播放新歌
      app.globalData.imgRotate = 0
      console.log(\'播放新歌\')
      backgroundAudioManager.title = item.name
      backgroundAudioManager.epname = album.name
      backgroundAudioManager.singer = item.author
      backgroundAudioManager.coverImgUrl = album.poster
      // 设置了 src 之后会自动播放
      backgroundAudioManager.src = item.src
    }
    let lyric = Base64.decode(item.lyric)
    this.setData({
      item: item,
      coverImg: album.poster,
      playStatus: !backgroundAudioManager.paused,
      duration: this.stotime(backgroundAudioManager.duration),
      currentPosition: this.stotime(backgroundAudioManager.currentTime),
      parseLyric: new Lyric(lyric, this.handleLyric),
      mode: app.globalData.mode,
      imgRotate: app.globalData.imgRotate
    })
    this.data.parseLyric.seek(backgroundAudioManager.currentTime*1000)
    console.log(this.data.playStatus, \'playStatus\')
    if (backgroundAudioManager.paused) {
      this.data.parseLyric.togglePlay()
    } else if (!this.data.timee) {
      this.toRotate()
    }
    backgroundAudioManager.onPlay(this.onPlay) // 监听背景音频播放事件
    backgroundAudioManager.onPause(this.onPause) // 监听背景音频暂停事件
    backgroundAudioManager.onTimeUpdate(this.onTimeUpdate) // 监听背景音频播放进度更新事件
    backgroundAudioManager.onEnded(this.onEnded) // 监听背景音频自然播放结束事件
    wx.setNavigationBarTitle({
      title: item.name
    })
    console.log(app.globalData.playList.length, \'app.globalData.playList.length\')
    if (app.globalData.playList.length == 1) {
      this.setData({
        isDel: true
      })
    }
  },
  handleLyric({lineNum, txt}) { // 歌词回调
    console.log(lineNum, txt, \'txt\')
    this.setData({
      lineLyric: txt
    })
  },
  onPlay() {
    const backgroundAudioManager = wx.getBackgroundAudioManager()
    console.log(\'onPlay\')
    console.log(backgroundAudioManager.duration, \'backgroundAudioManager.duration\')
    this.setData({
      playStatus: true
    })
    this.data.parseLyric.seek(backgroundAudioManager.currentTime*1000)
    this.toRotate()
  },
  onPause() {
    clearInterval(this.data.timee)
    this.data.parseLyric.stop()
    console.log(\'onPause\')
    this.setData({
      playStatus: false
    })
  },
  switch() { // 切换歌曲播放状态
    if (this.data.playStatus) { // 切换为暂停状态
      const backgroundAudioManager = wx.getBackgroundAudioManager()
      backgroundAudioManager.pause()
    } else { // 切换为播放状态
      const backgroundAudioManager = wx.getBackgroundAudioManager()
      backgroundAudioManager.play()
    }
  },
  onTimeUpdate() {
    const backgroundAudioManager = wx.getBackgroundAudioManager()
    let sliderValue = backgroundAudioManager.currentTime / backgroundAudioManager.duration * 100
    this.setData({
      currentPosition: this.stotime(backgroundAudioManager.currentTime),
      sliderValue: sliderValue,
      duration: this.stotime(backgroundAudioManager.duration)
    })
    // this.data.parseLyric.seek(backgroundAudioManager.currentTime*1000)
  },
  toRotate() {
    this.data.timee && clearInterval(this.data.timee)
    this.data.timee = setInterval(() => {
      app.globalData.imgRotate  = app.globalData.imgRotate + 0.8
      this.setData({
        imgRotate: app.globalData.imgRotate
      })
    }, 35)
  },
  onEnded() {
    console.log(\'onEnded\')
    this.setData({
      playStatus: false
    })
    if (this.data.mode == \'multiple\') {
      this.cutNext()
    } else {
      const backgroundAudioManager = wx.getBackgroundAudioManager()
      // 设置了 src 之后会自动播放
      backgroundAudioManager.src = this.data.item.src
    }
  },
  slideChange(e) { // 拖动滑块
    let value = e.detail.value
    this.setData({
      sliderValue: value
    })
    const backgroundAudioManager = wx.getBackgroundAudioManager()
    let currentTime = (value / 100) * backgroundAudioManager.duration
    backgroundAudioManager.seek(currentTime)
    this.data.parseLyric.seek(currentTime*1000)
  },
  cutPrev() { // 上一首
    this.delSongChange(\'prev\')
  },
  cutNext() { // 下一首
    this.delSongChange(\'next\')
  },
  delSongChange(type) { // 切换歌曲
    if (this.data.duration !== 0 && !this.data.isDel) {
      if (app.globalData.playList.length > 1) {
        clearInterval(this.data.timee)
      }
      this.data.duration = 0
      this.data.parseLyric.stop()
      if (type == \'prev\') {
        if (app.globalData.playIndex > 0) {
          app.globalData.playIndex --
        } else {
          app.globalData.playIndex = app.globalData.playList.length - 1
        }
      } else {
        if (app.globalData.playIndex < app.globalData.playList.length - 1) {
          app.globalData.playIndex ++
        } else {
          app.globalData.playIndex = 0
        }
      }
      let item = app.globalData.playList[app.globalData.playIndex]
      wx.setNavigationBarTitle({
        title: item.name
      })
      const backgroundAudioManager = wx.getBackgroundAudioManager()
      backgroundAudioManager.title = item.name
      backgroundAudioManager.singer = item.author
      // 设置了 src 之后会自动播放
      backgroundAudioManager.src = item.src
      let lyric = Base64.decode(item.lyric)
      this.setData({
        item: item,
        playStatus: !backgroundAudioManager.paused,
        parseLyric: new Lyric(lyric, this.handleLyric)
      })
      this.data.parseLyric.seek(backgroundAudioManager.currentTime*1000)
      console.log(this.data.playStatus, \'playStatus\')
      if (backgroundAudioManager.paused) {
        this.data.parseLyric.togglePlay()
      }
    }
  },
  // 改变播放模式
  changeMode() {
    if (this.data.mode == \'multiple\') {
      this.setData({
        mode: \'single\'
      })
    } else {
      this.setData({
        mode: \'multiple\'
      })
    }
    app.globalData.mode = this.data.mode
  },
  // 时间格式转换
  stotime(s) {
    let t = \'\'
    if (s > -1) {
      let min = Math.floor(s / 60) % 60;
      let sec = Math.floor(s) % 60
      if (min < 10) { t += \'0\' }
      t += min + \':\'
      if (sec < 10) { t += \'0\' }
      t += sec
    }
    return t
  },
  onUnload() { // 页面卸载
    const backgroundAudioManager = wx.getBackgroundAudioManager()
    backgroundAudioManager.onTimeUpdate()
    backgroundAudioManager.onPlay()
    backgroundAudioManager.onPause()
    this.data.parseLyric.stop()
    clearInterval(this.data.timee)
  },
})

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
微信小程序智能语音识别 - 黄建军~万事皆项目发布时间:2022-07-18
下一篇:
微信小程序音乐播放器发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap