一个微信小程序音频列表播放的页面遇到的坑及实现代码

不说别的,先上效果图。表示微信小程序createAudioContext的坑真的是成堆成堆的。

 

坑一:ios动态更换音频播放地址后 onCanplay 不执行

这个bug至今无解,当然这里也就不累赘onCanplay不加timeout获取不到音频总时长了,事实是就算加了ios也获取不到第二条音频的总时长,但是安卓没问题。直接说解决方案吧。

楼主比较幸运,展示的音频有限,本来也是指望onCanplay动态获取音频总长的,后来没办法直接提前获取到写死代码里了。至于切换音频之后更改右下角显示的总时长,这部分代码写到了onplay里

 

坑二:onxxx 事件需要取消监听

不取消的后果是什么呢?就是下次点击的时候前几次监听的事件一起触发。

 

 

下面是代码:

wxss:

/* inner/pages/sleep/sleep.wxss */
@import "../../../templates/loading/loading.wxss";

page{background: #efeff4;}
.container{width: 750rpx;}


/* fullBg */
.fullBg{padding: 50rpx 30rpx 150rpx;}
.fullBg .eachFull{width: 330rpx;position: relative;margin: 15rpx 0;}
.fullBg .eachFull:nth-child(2n-1){float: left;}
.fullBg .eachFull:nth-child(2n){float: right;}

.sleepBg{display:block;width: 100%;height: 350rpx;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;position: relative;}
.sleepBg image{width: 100%;height: 100%;display: block;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;}
.sleepBg .sleepCover{width: 100%;height: 100%;position: absolute;background: rgba(255, 255, 255, .15);border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;top: 0;left: 0;}
.sleepCont{width: 100%;padding: 30rpx 20rpx;border-bottom-left-radius: 20rpx;border-bottom-right-radius: 20rpx;box-sizing: border-box;background: #fff;}
.sleepCont text{display: block;float: left;line-height: 50rpx;width: 220rpx;}
.sleepCont image{display: block;float: right;width: 50rpx;height: 50rpx;}


/* player */
.player{width: 750rpx;position: fixed;bottom: 0;left: 0;height: 120rpx;border-top: 1rpx solid #ccc;text-align: center;box-sizing: border-box;background: #fff;}
.musicBg{width: 750rpx;height: 120rpx;display: block;}
.musicBg image{width: 750rpx;height: 120rpx;display: block;}
.playerBtns{width: 750rpx;height: 120rpx;position: absolute;top: 0;left: 0;padding-top: 10rpx;}
.leftAdjust{margin-left: 20rpx;}
.leftAdjust.lastAdjust{margin-right: 10rpx;margin-left: 10rpx;}
.playerAdjust{width: 80rpx;height: 80rpx;float: left;margin-top: 10rpx;}
.playerHandler{float: left;}
.playerHandler image{width: 100rpx;height: 100rpx;display: block;}
.progressBar{float: right;width: 250rpx;height: 10rpx;border-radius: 10rpx;background: #ccc;margin-top: 40rpx;margin-right: 20rpx;position: relative;}
.progressBarInner{position: absolute;height: 10rpx;background: #d74518;top: 0;left: 0;border-radius: 10rpx;}
.progressTime{float: right;line-height: 80rpx;margin-top: 5rpx;font-size: 24rpx;width: 180rpx;text-align: left;}

 

wxml:







  
    
      
        
        
      
      
      
        {{ item.name }}
        
        
      
    
  


  

    
      
      
        
        
      
      
      {{ currentTime }} / {{ totalTime }}
      
        
      
    
    
  
  


 

js:

// inner/pages/sleep/sleep.js
const mta = require('../../../utils/mta_analysis.js')
const dataset = require('../../../utils/data.js');
const { backend_url, wx_token } = require('../../../constants.js')
const app = getApp()




Page({

  /**
   * 页面的初始数据
   */
  data: {
    songDetail : [
      { name: '晨渐', total: 400.039184}, 
      { name: '穿过森林', total: 372.68898}, 
      { name: '水彩的素描', total: 367.725714},
      { name: '春风微风',  total: 229.093878 },
      { name: '回想', total: 369.632653 },
      { name: '水纹', total: 358.739592 },
      { name: '薰衣草香时', total: 458.475102 },
      { name: '森之树', total: 413.23102 },
      { name: '小春气息', total: 365.087347 }, 
      { name: '水蓝的梦', total: 377.443265}
    ],
    audioArr:[],
    currentIndex:null,
    playing:false,
    font:{},
    stay_start_time: null,
    audioTotal:0,
    audioDuration:0,
    currentTime:'00:00',
    totalTime:'00:00',
    playInterval:null,
    playRate:0,
    loading: {
      isLoading: true,   //加载
    },
  },


  update(){
    const that = this
    clearInterval(that.data.playInterval)

    that.data.playInterval = setInterval(function(){
      let audioDuration = that.data.audioDuration - 1

      if (audioDuration > 0){
        var min = parseInt(audioDuration / 60);
        var sec = parseInt(audioDuration % 60);
        if (min.toString().length == 1) {
          min = `0${min}`;
        }
        if (sec.toString().length == 1) {
          sec = `0${sec}`;
        }
        let rate = (that.data.audioTotal - audioDuration) / that.data.audioTotal * 100

        that.setData({
          audioDuration: audioDuration,
          currentTime: `${min}:${sec}`,
          playRate: rate
        })
      }
      
    }.bind(that),1000)

  },




  onEnd(){
    let that = this
    clearInterval(that.data.playInterval)
    that.setData({
      audioDuration: 0,
      totalTime: '00:00',
      currentTime: '00:00',
      playRate: 0,
      playing:false
    });
  },


  play(index, start){
    const that = this

    console.log(start)
    if (that.data.currentIndex != null){
      that.innerAudio.offPlay()
      that.innerAudio.offWaiting()
      that.innerAudio.offCanplay()
      that.innerAudio.offEnded()
    }

    that.setData({
      audioArr: that.data.audioArr,
      currentIndex: index,
      playing: true
    })
    

    that.innerAudio.play()

    that.innerAudio.onPlay(() => {
      
      if (start){
        let total = that.data.audioArr[index].total
        console.log(total)
        var min = parseInt(total / 60);
        var sec = parseInt(total % 60);
        if (min.toString().length == 1) {
          min = `0${min}`;
        }
        if (sec.toString().length == 1) {
          sec = `0${sec}`;
        }
        console.log(min, sec)
        that.setData({
          audioTotal: total,
          audioDuration: total,
          totalTime: `${min}:${sec}`,
          currentTime: `${min}:${sec}`
        });

      }
      
      that.update()
    })

    that.innerAudio.onWaiting(() => {
      console.log('wait')
    })


    that.innerAudio.onCanplay(() => {
      console.log('canplay')
      
    })


    
    that.innerAudio.onEnded(() => {
      that.onEnd()
      that.play(index, true)
    })
  },
  


  // 列表播放音乐 -- 方式三
  playSong(e){

    let that = this
    const index = e.currentTarget.dataset.index
    that.innerAudio.src = that.data.audioArr[index].url;

    if (index != that.data.currentIndex){
      that.setData({
        audioDuration: 0,
        totalTime: '00:00',
        currentTime: '00:00',
        playRate: 0
      });
      that.play(index, true)
    }
    
  },


  // 开关播放音乐 -- 方式三
  playNow(){
    const that = this
    const index = that.data.currentIndex

    if (index == null){
      that.innerAudio.src = that.data.audioArr[0].url;
      that.play(0, true)
    }else{
      that.play(index, false)
    }
    
  },


  // 暂停播放音乐 -- 方式三
  pauseNow(){
    const that = this
    // non - active
    for (var i = 0; i < that.data.audioArr.length; i++) {
      that.data.audioArr[i].play = false;
    }

    that.setData({
      playing: false,
      audioArr: that.data.audioArr
    })
    that.innerAudio.pause()
    clearInterval(that.data.playInterval)
  },



  // 播放上一个 -- 方式三
  playFront(){
    const that = this
    if (that.data.currentIndex == 0){
      wx.showToast({
        title: '当前为第一首',
        icon:"none"
      })
    }else{
      const index = that.data.currentIndex - 1;
      that.innerAudio.src = that.data.audioArr[index].url;

      that.setData({
        audioDuration: 0,
        totalTime: '00:00',
        currentTime: '00:00',
        playRate: 0
      });

      that.play(index, true)

    }
  },


  // 播放下一个 -- 方式三
  playNext(e){
    let that = this
    if (that.data.currentIndex == that.data.audioArr.length - 1){
      wx.showToast({
        title: '当前为最后一首',
        icon: "none"
      })
    }else{
      const index = that.data.currentIndex + 1;
      that.innerAudio.src = that.data.audioArr[index].url;

      that.setData({
        audioDuration: 0,
        totalTime: '00:00',
        currentTime: '00:00',
        playRate: 0
      });

      that.play(index, true)

    }
  },


  getData(){
    let that = this
    wx.request({
      url: backend_url + '/music_urls',
      method: 'GET',
      header:{
        'Authorization': wx_token
      },
      success: (res) => {
        console.log(res)

        let rawArr = []
        let songDetail = that.data.songDetail

        that.data.loading.isLoading = false
        that.setData({
          loading: that.data.loading
        })
        
        if(res.data.length > 0){
          let len = res.data.length - 1
          console.log(len)
          for (var i = len; i >= 0; i--){
            // console.log(i)
            let _i = i

            rawArr.push({
              url: backend_url + res.data[i],
              poster: "../images/sleep" + _i + ".jpg",
              name: songDetail[_i].name,
              total: songDetail[_i].total
            })

            if (_i == 0){
              that.setData({
                audioArr: rawArr
              })
            }

          }         
        }

      }
    })

  },




  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let that = this
    that.setData({
      font: app.globalData.font
    })

    wx.setInnerAudioOption({
      obeyMuteSwitch: false
    })
    that.innerAudio = wx.createInnerAudioContext()

    let now = new Date().getTime()
    mta.Event.stat('scan_route', { 'params': app.globalData.userId + '_' + now + '_sleep' })

    that.getData()

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    
    let that = this
    let time = new Date()

    that.setData({
      stay_start_time: time
    })

    // mta.Event.stat('sroute', { 'route': '睡眠' })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    let that = this
    // 停止播放
    // innerAudio.stop()
    clearInterval(that.data.playInterval)
    that.setData({
      playing:false
    })
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    let that = this

    // 停止播放
    that.innerAudio.stop()
    clearInterval(that.data.playInterval)
    let gap_final = dataset.dealSeconds(that.data.stay_start_time)

    mta.Event.stat('duration_recovery_sleep', { 'params': app.globalData.userId + '_' + gap_final })

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },

})

 

你可能感兴趣的:(一个微信小程序音频列表播放的页面遇到的坑及实现代码)