微信小程序音频播放器(wx原生)

351 阅读2分钟

记录一下本次播放器的写法


image.png

记录一下本次播放器的微信小程序原生写法,暂时是实现了,不知道还有没有其他更好的方式,还有个小bug第一次滑动进度条的时候,因为没有获取到时间,跳转位置不是很正确。

结构及样式

      <!-- 播放器 -->
      <view class="video">
        <view class="video-btn" bind:tap="handelVdeioFn">
          <view wx:if="{{!isPlay}}" class="iconfont icon-24gf-playCircle"></view>
          <view wx:else class="iconfont icon-zanting"></view>
        </view>
        <view class="video-loading">
          <slider bindchange="handelSliderChangeFn" bindchanging="handelSliderStartFn" max="{{sliderMax}}"  value="{{sliderCurrent}}" activeColor="#fed615" block-size="12" block-color="#fed615"/>
        </view>
        <view class="video-time">{{currentTime}}/{{duration}}</view>
      </view>
.video-box{
 padding: 25rpx;
}
.video-box .video{
 display: flex;
 justify-content: space-between;
 align-items: center;
 padding: 0 15rpx;
 width: 100%;
 height: 75rpx;
 border-radius: 60rpx;
 background-color: #019d76;
}

.video-btn:active{
 opacity: 0.8;
}

.video .iconfont{
 font-size: 50rpx;
 color: white;
}

.video-loading{
 flex:1
}
.video-time{
 color: white;
 font-size: 25rpx;
}

js

  /**
   * 页面的初始数据
   */
  data: {
    isPlay: false, // 是否播放
    duration: '00:00',// 总时长
    currentTime: '00:00',// 当前播放进度
    innerAudioContext: null, // 音频对象
    sliderMax: 100,// 读条最大值
    sliderCurrent: 0,// 读条当前值
    isDraggingSlider: false, // 是否在拖动读条
  },


  // 开启/关闭音频
  handelVdeioFn() {
    // 切换开启/关闭按钮
    this.setData({ isPlay: !this.data.isPlay })
    // 省略this.data
    const innerAudioContext = this.data.innerAudioContext
    // 判断当前状态
    if (this.data.isPlay) {
      innerAudioContext.play() // 播放
    } else {
      innerAudioContext.pause() // 暂停(下次播放会从暂停处开始)
    }
  },

  // 拖动进度条事件开始事件
  handelSliderStartFn() {
    // 设置当前状态为拖动中
    this.setData({ isDraggingSlider: true });
  },

    // 拖动进度条事件
  handelSliderChangeFn(e) {
    console.log(e);
    // 省略this.data
    const innerAudioContext = this.data.innerAudioContext
    // 先暂停(不先暂停直接跳转进度监控会失效)
    innerAudioContext.pause()
    // 根据进度条的值来跳转
    innerAudioContext.seek(e.detail.value)
    // 延迟400毫秒后播放(不延迟进度监控也会失效,延迟太久播放时间会不正确)
    setTimeout(() => {
      this.setData({
        isDraggingSlider: false, // 设置拖动状态结束
        isPlay:true, // 切换为播放图标
      })
      // 开始播放
      innerAudioContext.play()
    }, 400)
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
      // 创建音频上下文对象
    this.data.innerAudioContext = wx.createInnerAudioContext();
    const innerAudioContext = this.data.innerAudioContext
    // 音频资源的地址
    innerAudioContext.src = 'https://freetyst.nf.migu.cn/public%2Fproduct9th%2Fproduct46%2F2023%2F05%2F0611%2F2018%E5%B9%B408%E6%9C%8824%E6%97%A511%E7%82%B918%E5%88%86%E7%B4%A7%E6%80%A5%E5%86%85%E5%AE%B9%E5%87%86%E5%85%A5SONY192%E9%A6%96%2F%E5%85%A8%E6%9B%B2%E8%AF%95%E5%90%AC%2FMp3_64_22_16%2F6005970UKTA110755.mp3?Key=6bb3abbdf9c64505&Tim=1702875394130&channelid=01&msisdn=b2b46f01b426420eb9acb247e3ec89cb'

    // 监听音频播放进度更新事件
    innerAudioContext.onTimeUpdate(() => {
      // 当进度条在拖动时,不要更新进度
      if (!this.data.isDraggingSlider) {
        this.setData({
          currentTime: getTimes(innerAudioContext.currentTime),
          duration: getTimes(innerAudioContext.duration),
          sliderCurrent: Math.round(innerAudioContext.currentTime),
          sliderMax: Math.round(innerAudioContext.duration),
        })
      }
    })

    // 监听音频自然结束事件
    innerAudioContext.onEnded(() => {
      // 跳转至0 (不这样第二次播放进度就又不监听了)
      this.data.innerAudioContext.seek(0)
      // 这次延迟是为了显示完最后一秒
      setTimeout(()=>{
        this.setData({
          isPlay: false, // 是否播放
          currentTime: '00:00',// 当前播放进度
          sliderCurrent: 0,// 读条当前值
        })
      },500)
    })
  },


  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
    // 页面隐藏时停止音频播放并移除监听器
    this.data.innerAudioContext.pause();
    this.data.innerAudioContext.offTimeUpdate();
    this.data.innerAudioContext.destroy()
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    // 页面卸载时移除监听器,防止内存泄漏
    this.data.innerAudioContext.offTimeUpdate();
    this.data.innerAudioContext.destroy()
  },

})
// getTimes
export const  getTimes=(t)=> {
  let h = parseInt(t / 60 / 60 % 24)
  let m = parseInt(t / 60 % 60)
  let s = parseInt(t % 60)
  //三元表达式 补零 如果小于10 则在前边进行补零 如果大于10 则不需要补零
  h = h < 10 ? '0' + h : h
  m = m < 10 ? '0' + m : m
  s = s < 10 ? '0' + s : s
// return `${h}:${m}:${s}`
return `${m}:${s}`
}