zoukankan      html  css  js  c++  java
  • 微信小程序——音频播放器

    先来个效果图韵下味:

    需求:

    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);
          }
        }
      }
    })

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

  • 相关阅读:
    Commons JXPath
    10到十分精彩的智力题,你能过关几道?
    程序员下班电脑不关机的5大原因,你中招了吗?
    程序员下班电脑不关机的5大原因,你中招了吗?
    MySQL的一些概念笔记
    MySQL的一些概念笔记
    Shell中I/O重定向的用法笔记
    Shell中I/O重定向的用法笔记
    Shell重定向的概念笔记
    Shell重定向的概念笔记
  • 原文地址:https://www.cnblogs.com/sese/p/11310806.html
Copyright © 2011-2022 走看看