开发微信小程序中遇到一个需求:需要能做到播放暂停音频,同时能够实时显示时间进度条(当然,进度条可拖拽),另外还要能够左右切换音频播放。
所以就想到了微信小程序原生的方法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()
}
},
})
以上就是一个简单的小程序音频播放案例,除了样式外,功能基本能满足日常需求。
