刚开始想着有没有现成的组件可以直接用,找到了微信的媒体组件 audio,奈何看着 1.6.0版本开始,该组件不再维护。就百度了一下,还好有另一种方式,使用 InnerAudioContext 来实现音频播放


点击播放,播放按钮改变为暂停,播放后展示进度条,可 拖动/点击 进度条实现进度控制,可设置倍速
没有UI设计,所以界面很丑,界面后续完善,功能实现就行啦??
WXML:


1 <view class="item-con"> 2 <block wx:for="{{audios}}" wx:index="idx" wx:item="item" wx:key="idx"> 3 <view class="audio-item"> 4 <view class="audio-info"> 5 <text>{{index+1+"."+item.name}}</text> 6 <view wx:if="{{audioDisplay!=item.id||paused}}" class="audio-btn" bindtap="audioPlay" data-info="{{item}}">播放</view> 7 <view wx:else class="audio-btn btn-pause" bindtap="audioPause">暂停</view> 8 </view> 9 <view class="audio-control" wx:if="{{audioDisplay==item.id}}">10 <!-- 时长 -->11 <view class="audio-number">{{forNowTime?forNowTime:0}}s</view>12 <slider class="audio-slider" activeColor="#5189FF" block-size="12" value="{{current}}" max="{{duration}}" step="0.01" bindchanging="audioChanging" bindchange="audioChange">13 </slider>14 <view class="audio-number">{{forAllTime?forAllTime:0}}s</view>15 <!-- 倍速控制 -->16 <view class="audio-number speed" bindtap="setSpeed">17 x{{doubleSpeed}}18 <view wx:if="{{doubleSpeedSet}}" class="speed-wa" catchtap="setSpeedClose"></view>19 <view wx:if="{{doubleSpeedSet}}" class="double-speed">20 <view class="speed-item" catchtap="setSpeedTo" data-num="0.5">x0.5</view>21 <view class="speed-item" catchtap="setSpeedTo" data-num="1.0">x1.0</view>22 <view class="speed-item" catchtap="setSpeedTo" data-num="1.5">x1.5</view>23 <view class="speed-item" catchtap="setSpeedTo" data-num="2.0">x2.0</view>24 </view>25 </view>26 </view>27 </view>28 </block>29 </view>
JS


1 // 创建音频播放实例 2 const myAudio = wx.createInnerAudioContext() 3 4 Page({ 5 /** 6 * 页面的初始数据 7 */ 8 data: { 9 audios: [{ 10 id: 1, 11 name: "秒针", 12 src: "https://sharefs.ali.kugou.com/202202121104/0639f9c2315cbb939aff741be27860ff/KGTX/CLTX001/02c4d6fefd5d899081ba45f47be48adb.mp3" 13 }, 14 { 15 id: 2, 16 name: "做酒", 17 src: "https://sharefs.ali.kugou.com/202202121113/38ab5022041cea53ccff0752d481f818/KGTX/CLTX001/8fa49a75490d252a624c3e1872a26261.mp3" 18 }, 19 { 20 id: 3, 21 name: "好想抱住你", 22 src: "https://sharefs.ali.kugou.com/202202121104/7aa9c439b799ea26ace0fee414aa9c12/KGTX/CLTX001/43f9b75efe102a48ab20131dcaa2b557.mp3" 23 }, 24 { 25 id: 4, 26 name: "红尘彼岸却无她", 27 src: "https://sharefs.ali.kugou.com/202202121113/59831d34060f1dfcd2a114e74879868a/KGTX/CLTX001/8a57fbfe87af1dbcac1e9115a2ff1a06.mp3" 28 }, 29 ], 30 // 音频播放控制 31 audioDisplay: null, //当前播放的音频,用于显示播放时长进度条等 32 forNowTime: '0', //当前播放时间 33 forAllTime: '0', //总时长 34 duration: 0, //总时间 秒 35 current: 0, //slider当前进度 36 seek: false, //是否处于拖动状态 37 paused: true, //是否处于暂停状态 38 doubleSpeed: 1.0, //播放倍速 默认1.0 39 doubleSpeedSet: false //倍速设置小弹窗 40 }, 41 42 /** 43 * 生命周期函数--监听页面加载 44 */ 45 onLoad: function (options) {// 音频播放初始化 46 this.audioInit() 47 }, 48 49 // 音频播放-初始化 50 audioInit() { 51 // 设置音频播放倍速,此处若不设置,页面上点击设置倍速就不会产生效果 52 myAudio.playbackRate = 1.0 53 // 播放监听 54 myAudio.onPlay(() => { 55 console.log('开始播放') 56 console.log(myAudio.playbackRate); 57 }) 58 // 暂停监听 59 myAudio.onPause(() => { 60 console.log('停止播放') 61 }) 62 // 监听音频进入可以播放状态的事件。但不保证后面可以流畅播放,必须要这个监听,不然播放时长更新监听不会生效,不能给进度条更新值 63 myAudio.onCanplay(() => { 64 myAudio.duration 65 }) 66 // 播放时长更新监听 67 myAudio.onTimeUpdate(() => { 68 // 监听播放进度,更新页面播放时长和进度条进度 69 this.setData({ 70 forNowTime: parseInt(myAudio.currentTime), 71 forAllTime: parseInt(myAudio.duration), 72 current: myAudio.currentTime, 73 duration: myAudio.duration 74 }) 75 }) 76 // 播放出错监听 77 myAudio.onError((res) => { 78 console.log(res.errMsg) 79 console.log(res.errCode) 80 }) 81 }, 82 83 // 开始播放 84 audioPlay(val) { 85 console.log("点击了播放按钮", val); 86 if (val) { 87 // 展示当前播放音频的进度条 88 this.setData({ 89 audioDisplay: val.currentTarget.dataset.info.id 90 }) 91 // 设置当前播放音频的路径 92 myAudio.src = val.currentTarget.dataset.info.src 93 } 94 // 将暂停状态赋值为false 95 this.setData({ 96 paused: false, 97 }) 98 // 播放 99 myAudio.play()100 },101 102 // 暂停播放103 audioPause() {104 // 将暂停状态赋值为true105 this.setData({106 paused: true,107 })108 // 暂停109 myAudio.pause()110 },111 112 // 进度条改变113 audioChanging(val) {114 // 通过 seek 来更改当前播放实例的进度115 myAudio.seek(val.detail.value)116 // 界面显示滑动的时间同步改变117 this.setData({118 forNowTime: parseInt(val.detail.value)119 })120 },121 122 // 进度条改变完成123 audioChange(val) {124 myAudio.seek(val.detail.value)125 },126 127 // 点击设置倍速,弹出小弹窗128 setSpeed() {129 this.setData({130 doubleSpeedSet: true131 })132 },133 134 // 设置倍速的具体值135 setSpeedTo(val) {136 // 需要转换为 Number ,否则不生效137 myAudio.playbackRate = Number(val.currentTarget.dataset.num)138 // 界面同步更改并关闭小弹窗139 this.setData({140 doubleSpeed: val.currentTarget.dataset.num,141 doubleSpeedSet: false142 })143 },144 145 // 小弹窗关闭146 setSpeedClose() {147 this.setData({148 doubleSpeedSet: false149 })150 },151 152 /**153 * 生命周期函数--监听页面隐藏154 */155 onHide: function () {156 // 暂停播放157 this.audioPause()158 },159 160 /**161 * 生命周期函数--监听页面卸载162 */163 onUnload: function () {164 // 停止播放165 this.audioPause()166 myAudio.stop()167 },168 })


这里播放时长和进度条为什么不用两个变量来控制

因为获取到的音频长度和当前播放位置是小数形式的,我只想进度条用小数来控制,而播放时间想显示整数,所以用了4个变量,当然也有其他更好的方法,后续会改进
