微信小程序——音频播放器

Posted sese

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序——音频播放器相关的知识,希望对你有一定的参考价值。

先来个效果图韵下味:

技术图片

 

需求:

  1. 音频的播放,暂停,中间按钮状态的变化,播放时实时更新播放进度;
  2. 前进15s,后退15s;
  3. 进度条拖动。

 

一开始想着这3个功能应该挺简单的。不就是播放,暂停,前进,后退么~呵~写的时候发现自己还是太年轻。当然,这跟自己的技术功底有关系。现在把我遇到的难点及要注意的点说一下~

  1. 需要设置一个名为seekPosition的全局变量,初始值为0。我们要在播放的时候实时记录播放的位置,存到该变量里,这是方便在前进15s 或 后退15s 时计算时间点。
  2. 前进15s时要判断剩余时间是否>15s,如果<15s,则返回到开始位置;
  3. 后退15s时要判断播放时间是否>15s,如果<15s,则返回到开始位置;
  4. 点击播放时,要先判断seekPisition是否>0,如果>0,则跳转到seekPosition的位置,并播放;
  5. 拖动时,要先让音频停止播放,拖动结束后,再播放音频。并且要计算拖动位置对应的时间。

 

完整代码:

wxml:

<view class=" audio-content">

  <image src="logo640x360" class="bg-blur"></image>
  <view class="bg-gray"></view>
  <view class="container-cover">
    <view class="cover">
      <image src="logo640x360" class="cover-image"></image>
      <view class="cover-tip">词不达意.mp3</view>

    </view>
  </view>
  <view class="audio-inner row item-center">
    <view class="audio-desc">currentProcess</view>
    <view class="audio-progress-wrap">
      <van-slider value="sliderValue" step="sliderStep" active-color="#09bb07" use-button-slot bind:change="onSliderChange" bind:drag="onSliderDrag">
        <view class="slider-button" slot="button"></view>
      </van-slider>
    </view>
    <view class="audio-desc">productDetail.duration</view>
  </view>

  <!-- 播放器控制条 -->
  <section class="speech-player js_control_bar">
    <view class="player-bar row  justify-center item-center">
      <view class="backward js_audio_backward" title="后退15s">
        <ss-icon name="back-15" size="32px" color="#fff" block="true" bind:click="backward" />
      </view>
      <view class="play" title="播放/暂停">
        <view class="circle-loading" wx:if="loading"></view>
        <ss-icon name="play-outline" size="50px" color="#fff" block="true" wx:if="pause" bind:click="audioPlay" />
        <ss-icon name="pause-outline" size="50px" color="#fff" block="true" wx:if="playing" bind:click="audioPause" />
      </view>
      <view class="forward js_audio_forward" title="前进15s">
        <ss-icon name="forward-15" size="32px" color="#fff" block="true" bind:click="forward" />
      </view>
    </view>
  </section>
</view>

这里面用到了有赞的小程序组件 icon组件 和 slider 组件。如果你要用的话把上面的 <ss-icon> 换成<van-icon>,并且需要自己找阿里矢量图标库查找对应的图标。

 

js:

// components/product/audio/index.js

let audioUrl = "",
  seekPosition = 0;
const audioContext = wx.createInnerAudioContext();

Component(
  options: 
    multipleSlots: true,
    addGlobalClass: true
  ,


  /**
   * 组件的属性列表
   */
  properties: 
    productId: Number,
  ,
  /**
   * 组件的初始数据
   */
  data: 
    pause: true,
    playing: false,
    loading: false,
    productDetail: ,
    audioDuration: 0,
    currentProcess: ‘00:00‘,
    sliderStep:1
  ,

  /**
   * 组件的方法列表
   */
  methods: 
    //音频播放
    audioPlay(e) 
      const _this = this;
      let audioDuration = _this.data.audioDuration;
      if (audioUrl) 
        if (seekPosition) 
          //如果有指定位置,则跳转到指定位置
          audioContext.seek(seekPosition);
        
        audioContext.play();
        _this.setData(
          pause: false,
          playing: true,
          loading: false,
        )
       else 
       //getJSON是我自己封装的
        ss.getJSON(‘获取音频如果需要发送请求,这里面放请求地址‘, 
          放你自己的参数
        , res => 
          audioUrl = res.t;
          audioContext.src = audioUrl;
          if (seekPosition) 
            audioContext.seek(seekPosition);
          
          audioContext.play();
          audioContext.onPlay(() => 
            console.log(‘onPlay‘)
          )

          audioContext.onWaiting(() => 
            console.log(‘onWaiting‘)
            _this.setData(
              pause: false,
              playing: false,
              loading: true,
            )
          )

          audioContext.onCanplay(() => 
            console.log(‘onCanplay‘)
            _this.setData(
              pause: false,
              playing: true,
              loading: false
            )
            setTimeout(() => 
              audioContext.duration
            , 500)

            _this.audiostatus();
          )

          audioContext.onError((res) => 
            console.log(res.errMsg)
          )
        )
      

    ,


    //播放暂停
    audioPause: function() 
      const _this = this;
      audioContext.pause();
      _this.setData(
        pause: true,
        playing: false,
        loading: false
      )
    ,

    //记录播放状态
    audioStatus: function() 
      const _this = this;
      //音频播放进度更新事件
      audioContext.onTimeUpdate(() => 
        seekPosition = audioContext.currentTime;
        _this.setData(
          currentProcess: ss.formatSecToMin(audioContext.currentTime),
          sliderValue: audioContext.currentTime / _this.data.audioDuration * 100,
        )
      )
      //音频播放结束
      audioContext.onEnded(() => 
        seekPosition = 0;
        _this.setData(
          sliderValue: 0,
          currentProcess: ‘00:00‘,
          playing: false,
          pause: true
        )
      )
    ,

    //开始拖动
    onSliderDrag(e) 
      const _this = this;
      if (_this.data.playing) 
        _this.audioPause()
      
      let sliderValue = e.detail.value;
      seekPosition = _this.data.audioDuration / 100 * sliderValue;
      _this.setData(
        currentProcess: ss.formatSecToMin(seekPosition)
      )

    ,

    //拖动结束
    onSliderChange(e) 
      const _this = this;
      _this.audioPlay()
    ,


    //前进15s
    forward() 
      const _this = this,
        audioDuration = _this.data.audioDuration;
      let currentTime;
      if (_this.data.playing) 
        currentTime = audioContext.currentTime;
      
      if (_this.data.pause) 
        currentTime = seekPosition;
      

      if (audioDuration - currentTime > 15) 
        seekPosition = currentTime + 15;
        _this.setData(
          sliderValue: seekPosition / audioDuration * 100,
          currentProcess: ss.formatSecToMin(seekPosition)
        );
       else 
        seekPosition = audioDuration;
        _this.setData(
          sliderValue: 0,
          currentProcess: ‘00:00‘
        );
      
      if (audioUrl && _this.data.playing) 
        audioContext.seek(seekPosition);
      
    ,

    //后退15s
    backward() 
      const _this = this,
        audioDuration = _this.data.audioDuration;
      let currentTime;
      if (_this.data.playing) 
        currentTime = audioContext.currentTime;
      
      if (_this.data.pause) 
        currentTime = seekPosition;
      

      if (currentTime > 15) 
        seekPosition = currentTime - 15;
       else 
        seekPosition = 0;
      
      _this.setData(
        sliderValue: seekPosition / audioDuration * 100,
        currentProcess: ss.formatSecToMin(seekPosition)
      );
      if (audioUrl && _this.data.playing) 
        audioContext.seek(seekPosition);
      
    
  
)

 

大概就是这些了~有更好解决方案的欢迎留言哈~~

 

以上是关于微信小程序——音频播放器的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序音频播放之音乐播放器

录音上传播放音频微信小程序实践

微信小程序背景音频播放

微信小程序音频播放

微信小程序背景音频播放分享功能

微信小程序——音频播放器