微信小程序自定義組件---音頻組件

最近客戶要求,在原有的音頻功能上改動,使用戶能夠拖動進度條進行控制音頻進度。

效果如下:

下面是代碼:

父組件,wxml:

<slider-audio audio-src="{{audioUrl}}"></slider-audio>

父組件,json:

"usingComponents": {
    "slider-audio": "../../components/audio/audio"
}

父組件,js:


Page({
  data: {
    audioUrl: "../../images/20191127164159_942.mp3"
  },
  onLoad: function(){

  }
})

子組件,wxml:

<view class="audio-container">
  <view class="audio-head">
    <image mode="widthFix" src="../../images/audio.png"></image>
  </view>
  <view class="audio-slider">
    <slider min="0" max="{{sliderMax}}" bindchange="sliderChange" block-size="14" value="{{sliderValue}}" activeColor="#eccb13" />
    <view class="audio-time">
      <text>{{currentTimeStr}}/{{durationTimeStr}}</text>
    </view>
  </view>
  <view class="audio-play" bindtap="changePlayState">
    <image mode="widthFix" src="{{audioPlay ? '../../images/pause.png' : '../../images/play.png'}}"></image>
  </view>
</view>

子組件,json:

{
  "component": true,
  "usingComponents": {}
}

子組件,css:

view,text,image,slider{
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.audio-container{
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.audio-head{
  width: 60rpx;
  height: 60rpx;
  flex-shrink: 0;
}
.audio-head image{
  width: 100%;
  height: 100%;
}
.audio-slider{
  width: 78%;
  position: relative;
  padding: 0 20rpx;
}
.audio-time{
  width: 100%;
  text-align: right;
  font-size: 24rpx;
  line-height: 28rpx;
}
.audio-play{
  width: 40rpx;
  height: 40rpx;
  flex-shrink: 0;
}
.audio-play image{
  width: 100%;
  height: 100%;
}

子組件,js:

// components/audio.js
Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    audioSrc: {
      type: String
    }
  },

  /**
   * 組件的初始數據
   */
  data: {
    audioPlay: false, //當前的播放狀態控制
    sliderValue: 0, //進度條最小值
    sliderMax: 100, //進度條最大值
    backgroundAudioManager: "", //播放實例
    currentTimeStr: "00:00", //當前進度的時間
    durationTimeStr: "00:00", //總的時間
    changeValState: false //在拉動進度條的時候,拉動完成的狀態
  },
  //生命週期函數列表
  lifetimes: {
    // 在組件實例進入頁面節點樹時執行
    attached: function () {
      console.log("播放資源", this.data.audioSrc);
      //this.creatAudio();

    },
    // 在組件實例被從頁面節點樹移除時執行
    detached: function () {

    }
  },
  /**
   * 組件的方法列表
   */
  methods: {
    creatAudio: function(){
      let that = this;
      that.data.backgroundAudioManager = wx.getBackgroundAudioManager();
      that.data.backgroundAudioManager.title = '音頻';

      that.data.backgroundAudioManager.onPlay(function () { //播放監聽
        console.log('播放!');
        that.setData({
          audioPlay: true
        })
      })
      that.data.backgroundAudioManager.onPause(function(){ //暫停監聽
        console.log('暫停播放!');
        that.setData({
          audioPlay: false
        })

      })
      that.data.backgroundAudioManager.onEnded(function(){ //結束播放監聽
        console.log('播放結束!');
        that.setData({
          audioPlay: false
        })
      })
      that.data.backgroundAudioManager.onError(function(res){// 播放失敗監聽
        console.log('播放音頻失敗' , res);
      })
      that.data.backgroundAudioManager.onSeeked(function(res){ //監聽結束跳轉事件callback(無效)
        console.log("結束跳轉", res);
        that.setData({
          changeValState: false
        })
      })
      that.data.backgroundAudioManager.onTimeUpdate(function (res) { //監聽背景音頻播放進度更新事件
        if (that.data.changeValState) return false;
        let currentTime = that.data.backgroundAudioManager.currentTime;
        let duration = that.data.backgroundAudioManager.duration;
        if (that.data.sliderMax==100){
          that.setData({
            sliderMax: duration.toFixed(0)
          })
        }
        let val = parseInt((currentTime / duration) * that.data.sliderMax);
        that.setData({
          sliderValue: val
        })
        let currTimeStr = that.formatTime(currentTime);
        let duraTimeStr = that.formatTime(duration);
        that.setData({
          currentTimeStr: currTimeStr,
          durationTimeStr: duraTimeStr
        })
      })
      
    },
    //滑動條改變事件
    sliderChange: function (e) {
      let that = this;
      console.log(e);
      that.setData({
        sliderValue: e.detail.value
      })
      if (that.data.backgroundAudioManager=="") return false;
      that.setData({
        changeValState: true
      })
      that.data.backgroundAudioManager.seek(e.detail.value);
      setTimeout(function(){
        that.setData({
          changeValState: false
        })
      },500)
    },
    //播放按鈕點擊事件
    changePlayState: function(){
      let that = this;
      this.setData({
        audioPlay: !this.data.audioPlay
      })
      if (this.data.audioPlay){
        if (!that.data.backgroundAudioManager.src) { //初始化給backgroundAudioManager.src賦值
          that.creatAudio();
          that.data.backgroundAudioManager.src = that.data.audioSrc; //當設置了src後會自動播放
        }
        that.data.backgroundAudioManager.play();
      } else {
        that.data.backgroundAudioManager.pause();
      }
    },
    formatTime: function(num){ //格式化時間格式
      num = num.toFixed(0);
      let second = (num%60);
      if(second<10) second = '0' + second;
      let min = Math.floor(num / 60);
      if (min < 10) min = '0' + min;
      return min+":"+second;
    }
  }
})

翻閱了微信小程序的很多api,發現只有這一個比較好用,其他的基本不是在開發工具上無法播放,就是在手機上無法播放,按理說,基礎庫版本都支持的,但是確實沒有任何反應,我微信開發者工具調試基礎庫爲:2.9.4,使用InnerAudioContext無法播放聲音,手機上可以。

另外,在這篇例子中,開發者工具和手機上都無法監聽到:backgroundAudioManager.onSeeked和backgroundAudioManager.onSeeking回調函數,不知道是小程序的bug還是我使用的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章