在微信小程序中,BackgroundAudioManager
是一个很棒、很实用的 API,他可以跨页面使用。
一般情况,音频(AudioContext)播放只在当前页面使用,一旦离开页面,就会自动停止播放。如果想在切换页面的时候保持音乐不停播,就要使用到 BackgroundAudioManager
才行。
BackgroundAudioManager
整个应用中只有一个实例,无论在哪个页面、哪个小程序的生命周期里,wx.getBackgroundAudioManager()
得到的实例都是同一个,可以自由的获取。
const backgroundAudioManager = wx.getBackgroundAudioManager();
// 每次播放音乐的时候,这三个是必要的,否则可能存在不能播放的情况
backgroundAudioManager.title = '此时此刻';
backgroundAudioManager.epname = '此时此刻';
backgroundAudioManager.singer = '许巍';
在做音乐播放的是,可能会遇见显示播放进度的需求,要么“00:00/01:00”这样文字的显示,要么进度条的方式。
BackgroundAudioManager
里面有几个非常棒的属性。
- currentTime [Number] 当前音频的播放位置(单位:s),只有在有合法 src 时返回。(只读)
- duration [Number] 当前音频的长度(单位:s),只有在有合法 src 时返回。(只读)
- src [String] 默认为空字符串,当设置了新的 src 时,会自动开始播放,目前支持的格式有 m4a, aac, mp3, wav。
有了这两个数据,进度就可以完美的显示出来。
AudioContext 也有这两个属性,遇见问题,可以尝试一下以下方式规避。
duration 当前音频的长度
在微信小程序中,它的规范时只读,只能被动的获取。
backgroundAudioManager.src = 'your aduio url';
console.log(backgroundAudioManager.duration);
假设如上获取一段音频的时长,会存在获取不到的情况,虽然更新了 src,但是音频初次播放需要一点时间加载,所以,立即响应可能获取不到对应的时长。
那么,当音频能播放的时候再去获取呢?
backgroundAudioManager.onCanplay(() => {
console.log(backgroundAudioManager.duration);
setTimeout(() => {
// Yes, I can
console.log(backgroundAudioManager.duration);
}, 500);
});
经过 Android 真机、微信开发者工具实测,也存在一定的几率获取不到时长。最后,通过一个延迟才获取到,具体延迟多少比较合适,暂时没有深究。
如果还不能获取,或者不能及时获取到,更新 src 后主动触发一下
backgroundAudioManager.play()
、backgroundAudioManager.pause()
currentTime 当前音频的播放位置
// 获取播放进度比例
const getProgress = () => {
const duration = backgroundAudioManager.duration;
// 可能还在初始化中
if(!duration || duration === 0) {
return 0;
}
// 当前音频位置
const currentTime = backgroundAudioManager.currentTime || 0;
return Math.floor((currentTime * 100) / duration);
}
// TODO 更新页面进度
let updateTimer;
const doUpdate = () => {
const p = getProgress();
}
当第一次播放音频的时候,起始会从 0 开始,快结束的时候也会接近最后的时长,但当音频播放停止,currentTime 的值会莫名其妙的比 当前音频的长度少几秒。
getBackgroundAudioManager播放时间问题,类似这个问题,在微信开发者工具没有这个问题,Android 机器上会存在。
当第二次播放的时候,currentTime 会从上次那个错误的结束时间开始,当音频准备好后,又从 0 开始,再到错误的结尾。
错误的结尾,通过一个变量记录音频是否已经停止播放,直接返回 0。
错误的开始,通过一个变量记录音频是否已经初始化好,没有初始化,进度是 0,初始化好后真实数据计算。
let initialized = false; // 是否初始化
let isEnd = true; // 是否已经结束
backgroundAudioManager.onCanplay(() => {
initialized = true;
});
backgroundAudioManager.onPlay(() => {
isEnd = false;
});
backgroundAudioManager.onEnded(() => {
isEnd = true;
initialized = false;
});
// 获取播放进度比例
const getProgress = () => {
if(!initialized) {
return 0;
}
if(isEnd) {
return 0;
// return 1;
}
const duration = backgroundAudioManager.duration;
// 可能还在初始化中
if(!duration || duration === 0) {
return 0;
}
// 当前音频位置
const currentTime = backgroundAudioManager.currentTime || 0;
return Math.floor((currentTime * 100) / duration);
}
具体业务中可能会涉及到 暂停 之类,暂不做分解。
最后,比较理想的获得了播放进度。
转载请注明:OnlyLing - Web 前端开发者 » 微信小程序 BackgroundAudioManager currentTime、duration 的问题以及如何规避