微信小程序音频播放带进度条显示以及音频切换功能

开发微信小程序中遇到一个需求:需要能做到播放暂停音频,同时能够实时显示时间进度条(当然,进度条可拖拽),另外还要能够左右切换音频播放。

所以就想到了微信小程序原生的方法wx.createInnerAudioContext(),完成的同时外送一个可倍速的功能。当然如果你的音频有不同角色的链接,还可以实现男女切换等功能。效果图如下:

案例图片

具体实现方法及部分源代码如下:

wxml部分代码

代码中引用的图片地址需要引用自己的,本案例只是做一个展示。

 <!-- 声音列表 -->
<view class="voiceBox">
  <view class="voice-list {{index == 0?'common-active':''}}" 
  wx:for="{{3}}"
  wx:key="index"
  bind:tap="getVoice">
    <view class="voice-number">0{{index+1}}</view>
    <view class="voice-text">test</view>
    <view class="voice-playBtn">
      <image src="img_off.png" mode="widthFix" ></image>
    </view>
  </view>
</view>
<!-- 控制按钮 -->
<view class="BtnBox">
  <!-- 切换男女生按钮 -->
  <view class="speakBtn" data-sex="men">
    <image src="icon_men.png" mode="widthFix" bind:tap="changePerson"/>
  </view>
  <view class="speedBtn" data-type="prev" bind:tap="changeVoice">
    <image src="icon_prev.png" mode="widthFix"/>
  </view>
  <view class="playBtn">
    <!-- 播放 -->
    <image wx:if="{{isPlaying}}" src="icon_on.png" mode="widthFix" bind:tap="pauseAudio" />
    <!-- 暂停 -->
    <image wx:else src="icon_off.png" mode="widthFix" bind:tap="playAudio" />
  </view>
  <view class="speedBtn" data-type="next" bind:tap="changeVoice">
    <image src="icon_next.png" mode="widthFix"/>
  </view>
  <view class="speed" data-speed="{{doubleSpeed}}" bind:tap="setSpeed">{{doubleSpeed}}X</view>
</view>

js部分代码

主要用到了创建音频实例(wx.createInnerAudioContext())、播放(InnerAudioContext.play())、暂停(InnerAudioContext.pause())、监听音频播放进度更新(InnerAudioContext.onTimeUpdate(function listener))、跳转到指定位置(InnerAudioContext.seek(number position))、倍速播放(playbackRate(number rate))等官方API。

Page({
  data: {
    isPlaying: false, // 是否正在播放
    currentSlider:0, // 当前进度条值
    currentSliderMax:0, // 进度条最大值
    currentTime: 0, // 当前播放进度
    duration: 120, // 音频总时长
    doubleSpeed: 1.0, // 播放倍速
    audioUrl:'1.mp3',
    isShowAudio:false, // 是否显示音频
    isShowAudioArrow:true,
  },
  /**
  * 生命周期函数--监听页面加载
  */
  onLoad(options) {},
  /**
  * 生命周期函数--监听页面初次渲染完成
  */
  onReady() {},
  /*
  *音频相关
  */
  // 初始化音频上下文
  initializeAudio(url) {
    // 每次调用音频方法之前判断当前页面是否有正在播放的实例
    if (this.audioContext) {
      // 停止当前播放
      this.audioContext.stop()
      // 销毁音频实例
      this.audioContext.destroy()
    }
    // 创建音频实例(延迟到获取URL后创建)
    this.audioContext = wx.createInnerAudioContext()
    // 设置音频地址
    this.audioContext.src = url
    this.setData({ 
      audioUrl: url
    })
   // 绑定事件监听
   // 设置事件监听
    this.audioContext.onCanplay(() => {
      let durationTime = this.audioContext.duration.toFixed(0)
      this.setData({ duration: this.formatTime(durationTime) })
    })
    // 监听音频播放进度更新事件
      this.audioContext.onTimeUpdate(() => {
        // 实时设置音频播放进度及音频的总时长
        this.setData({
          currentTime:this.formatTime(this.audioContext.currentTime),
          currentSlider:this.audioContext.currentTime,
          currentSliderMax:this.audioContext.duration,
          duration:this.formatTime(this.audioContext.duration.toFixed(0))
        })
      })
      // 监听音频自然播放至结束的事件
      this.audioContext.onEnded(() => {
         this.setData({ isPlaying: false, currentTime: 0 })
      })
      // 监听音频播放错误事件
      this.audioContext.onError(err => {
        this.handleError(`播放失败(${err.errCode})`)
      })
   },
  // 点击播放列表的方法,点击对应的音频并播放
  getVoice(){
    // 这里可以写异步请求,通过从后端获取音频地址
    let src = '1.mp3'
    // 获取到音频地址后调用音频初始化方法并判断是否播放
    this.initializeAudio(src)
    if (!this.data.audioUrl) {
      return;
    }
    this.audioContext.play()
    this.setData({
      isShowAudio:true,
      isPlaying:true
    })
  },
  // 播放音频按钮
  playAudio() {
    if (!this.data.audioUrl) {
      return;
    }
    this.audioContext.play();
    this.setData({
      isPlaying:true
    })
  },
  // 暂停播放按钮
  pauseAudio() {
    this.audioContext.pause();
    this.setData({
       isPlaying:false
    })
  },
  // 设置倍速
  setSpeed(e) {
    // 获取到你页面中存储的倍速数字
    const speed = Number(e.currentTarget.dataset.speed.toFixed(1))
    if(speed == 2){
      this.setData({ doubleSpeed: 0.5 });
      // 设置音频倍速方法
      this.audioContext.playbackRate = 0.5;
    }else {
      this.setData({ doubleSpeed: speed+0.5 });
      this.audioContext.playbackRate = speed+0.5;
    }
  },
  // 进度条拖动方法
  seekAudio(e) {
    // 获取进度条当前值
    const position = e.detail
    // 设置音频跳转到对应的时间
    this.audioContext.seek(position)
    // 同时赋值当前时间
    this.setData({ 
      currentTime: this.formatTime(position) 
    })
  },
  // 改变声源
  changePerson(){
    let src = 'woman.mp3'
    this.initializeAudio(src)
    this.audioContext.play()
    this.setData({
      isShowAudio:true,
      isPlaying:true
    })
  },
  // 切换下一个方法
  changeVoice(e){
    // 这里同样可以调用后台接口获取对应音频来播放
    let changeText = e.currentTarget.dataset.type
    if(changeText == 'prev'){
       let src = '2.mp3'
      // 获取到音频地址后调用我们的初始化方法
      this.initializeAudio(src)
    }else {
     let src = '3.mp3'
     this.initializeAudio(src)
    }
    // 播放音频
    this.audioContext.play()
    this.setData({
    isShowAudio:true,
    isPlaying:true
  })
  },
  // 时间格式化(秒 -> 分:秒)
  formatTime(seconds) {
    const min = Math.floor(seconds / 60)
    const sec = Math.floor(seconds % 60)
    return `${min}:${sec.toString().padStart(2, '0')}`
  },  
  /**
  * 生命周期函数--监听页面卸载
  */
  onUnload() {
    // 记得每次页面卸载后,销毁音频实例
    // 当然你也可以根据自己的需求销毁实例
    if (this.audioContext) {
      this.audioContext.stop()
      this.audioContext.destroy()
    }
  },

})

记得每次切换新的音频时,要销毁原有的音频实例,然后重新创建新的实例。每次页面卸载记得要销毁页面中的音频实例。

以上就是一个简单的小程序音频播放案例,除了样式外,功能基本能满足日常需求。

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇