开发微信小程序中遇到一个需求:需要能做到播放暂停音频,同时能够实时显示时间进度条(当然,进度条可拖拽),另外还要能够左右切换音频播放。
所以就想到了微信小程序原生的方法wx.createInnerAudioContext()
具体实现方法及部分源代码如下:
代码中引用的图片地址需要引用自己的,本案例只是做一个展示。
<!-- 声音列表 --> <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() } }, })
以上就是一个简单的小程序音频播放案例,除了样式外,功能基本能满足日常需求。