微信小程序:自定义音乐进度条

需求:显示音乐播放按钮、可手动拖拽进度条;页面中含多个音乐,播放当前音乐时暂停其他音乐播放。

小程序自带标签 audio
小程序自带的audio标签含固定的样式,且有最小尺寸。目前项目也不含name和author字段,所以放弃audio标签。

实现效果图
这里写图片描述


初始化音乐数据

<text>{{currentProcess}}</text>
<slider bindchange="" bindtouchstart="" bindtouchend="" max="{{totalProcessNum}}" min="0" value="{{currentProcessNum}}" disabled="{{canSlider}}"></slider>
<text>{{totalProcess}}</text>
<image src="{{audioListObj['q'+questionObj.id].imgUrl}}" data-audioId="q{{questionObj.id}}" bindtap="clickPlayAudio"></image>  <!-- clickPlayAudio 播放按钮触发事件 -->
src: _this.data.questionObj.audio,
currentProcess: '--:--',//显示 将currentProcessNum处理成时间形式展示
currentProcessNum: 0,//赋值
totalProcess: '--:--',
totalProcessNum: 1,
seek: -1,
imgUrl: '../../images/play.png',
canSlider: false    //是否可以滑动,防止加载音乐时 用户滑动进度条

点击播放按钮触发事件

说明:

  • 因页面中音乐数量较多,所以只有当用户点击播放,再去加载audio文件。

  • wx.getBackgroundAudioManager()对象,同一时间只会播放一个audio文件。当重新赋值src时,会切换文件。

  • 利用onTimeUpdate方法实时更新播放进度。

  • onEnded方法处理audio播放完毕后的数据重新初始化事件。

  • 变量clickPlayAudioFunctionIsRuning用来防止用户连续点击按钮。

    const _this = this;
    const _data = _this.data;
    //防止用户点击播放按钮太快
    if (_data.clickPlayAudioFunctionIsRuning){
      return ;
    }
    _this.setData({
      clickPlayAudioFunctionIsRuning: true
    })
    var _obj = _this.data.audioListObj;
    const audioId = $this.currentTarget.dataset.audioid;
    var backgroundAudioManager = wx.getBackgroundAudioManager();
    if (_this.data.audioListObj[audioId].imgUrl == '../../images/play.png'){
      console.log('转换至播放状态')
      //切换所有播放按钮为暂停状态
      for (var j in _this.data.audioListObj) {
        if (j && _this.data.audioListObj[j]) {
          _this.data.audioListObj[j].imgUrl = '../../images/play.png';
        }
      }
      _this.setData({
        audioListObj: _this.data.audioListObj,
      })
      //暂停正在播放音乐
      wx.stopBackgroundAudio();
      _obj[audioId].imgUrl = '../../images/paused.png';
      backgroundAudioManager.title = '测试';
      //设置音乐开始时间
      if (_this.data.audioListObj[audioId].currentProcessNum != 0){
        backgroundAudioManager.startTime = _this.data.audioListObj[audioId].currentProcessNum;
      }
      backgroundAudioManager.src = _this.data.audioListObj[audioId].src;
      _obj[audioId].canSlider = true;
      backgroundAudioManager.play();
      //    背景音频自然播放结束事件
      backgroundAudioManager.onEnded(function () {
        var _obj = _this.data.audioListObj;
        _obj[audioId].imgUrl = '../../images/play.png';
        _obj[audioId].currentProcess = 0;
        _obj[audioId].currentProcessNum = 0;
        _this.setData({
          audioListObj: _obj
        })
      })
      //背景音频播放进度更新事件
      backgroundAudioManager.onTimeUpdate(function (callback) {
        _obj = _this.data.audioListObj;
        //设置总时长
        if (_obj[audioId] && _obj[audioId].totalProcess && (_obj[audioId].totalProcess == '--:--' || _obj[audioId].totalProcess == '00:00')) {
          console.log(_this.formatTime(backgroundAudioManager.duration))
          _obj[audioId].totalProcess = _this.formatTime(backgroundAudioManager.duration);
          _obj[audioId].totalProcessNum = backgroundAudioManager.duration;
          _this.setData({
            audioListObj: _obj
          })
        }
        if (!_this.data.isMovingSlider) {
          //更新进度
          _obj[audioId].currentProcess = _this.formatTime(backgroundAudioManager.currentTime);
          _obj[audioId].currentProcessNum = backgroundAudioManager.currentTime;
          _this.setData({
            audioListObj: _obj
          })
        }
      })
    } else if (_this.data.audioListObj[audioId].imgUrl == '../../images/paused.png'){
      console.log('转换至暂停状态')
      _obj[audioId].imgUrl = '../../images/play.png'
      wx.pauseBackgroundAudio();
      backgroundAudioManager.pause();
    }

    _this.setData({
      audioListObj: _obj,
      clickPlayAudioFunctionIsRuning: false
    })

滑动进度条触发事件

const _this = this;
    const _data = _this.data;
    const _obj = _this.data.audioListObj;
    const position = $this.detail.value;
    const audioId = $this.currentTarget.dataset.audioid;
    var backgroundAudioManager = app.globalData.bgAudioListManager;
      _obj[audioId].currentProcess = _this.formatTime(position);
      _obj[audioId].currentProcessNum = position;

      //如果正在播放
      if (_obj[audioId].imgUrl == '../../images/paused.png'){
        _obj[audioId].seek = position;
        if (_obj[audioId].seek != -1) {
          wx.seekBackgroundAudio({
            position: Math.floor(position),
          })
          _obj[audioId].seek = -1;
        }
      }
      _this.setData({
        audioListObj: _obj
      })

开始滑动触发事件

this.setData({
      isMovingSlider: true
    });

结束滑动触发事件

 this.setData({
      isMovingSlider: false
    });

备注:

代码只用于参考,具体如何实现要结合自己的项目结构。


版权声明:本文为Akony原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。