最近写小程序时涉及到音频播放,自然是少不了getBackgroundAudioManager(),也为用户提供方便,可以通过系统的暂停/播放来同步控制小程序的音频的暂停/播放。
那么在使用的时候,我暂停了,调用了pause(),播放时我错在了直接给设置了歌曲的链接。
核心点在:判断当前的歌曲链接是不是被暂停的歌曲的链接,不是原来的歌就重新赋予链接地址,否则,是原来的歌,那就不赋予链接地址而是调用play()方法。
我的做法是:(思路是这样的,由于使用场景不同,所以下面的代码也不同)
1、先定义一个flag来记录当前的歌是新歌还是在播放的歌。
2、当点击播放按钮后:判断flag的值是true(新歌)还是false(在播放的歌)。
3、怎么看是不是新歌呢,就是这首歌还没播放过就算新歌,一点过播放了就不算新歌了。
【注意】:如果切歌了,请求到了新歌,又没给getBackgroundAudioManager()对象赋值新歌地址等信息,但是去调了play(),会出现按原音乐资源进行播放,也就是上一首歌,无论怎么切换,都会停在这首歌,因为getBackgroundAudioManager()对象的src没变。
4、如果是新歌就给getBackgroundAudioManager()对象赋值新歌地址等信息,否则就走play()。
data() {
return {
musicData:'',// 用于保存音乐数据
musicPlay:false,// 用于记录音乐按钮是播放还是暂停
isNewMusic:false,// 用于记录当前音乐是不是新音乐资源
bgAudioManager:null,// 用于接收getBackgroundAudioManager()的实例
}
},
onLoad() {
// 创建系统背景音乐实例对象--方便顶栏可以控制
this.bgAudioManager=uni.getBackgroundAudioManager();
this.bgAudioManager.onPlay(()=>{
this.musicPlay=true;
});
this.bgAudioManager.onPause(()=>{
this.musicPlay=false;
});
this.bgAudioManager.onStop(()=>{
this.musicPlay=false;
});
this.bgAudioManager.onEnded(()=>{
this.musicPlay=false;
})
// 初始化的时候就先获取音乐资源
this.getMusic().then(()=>{
this.isNewMusic=true;
})
},
// 拿网易的接口来测试获取音乐
getMusic(){
// 由于我要基于这个音乐资源的获取去设置“是否为新歌”的状态,所以定义了个Promise对象
return new Promise((resolve,reject)=>{
uni.request({
url:'https://api.uomg.com/api/rand.music',
data:{
sort:'热歌榜',
format:'json'
},
success:(res)=>{// 请求得到了响应
if(res.data.code==1){// 获取到了新歌
// 把新歌的数据存放到musicData中
this.musicData=Object.assign({},res.data.data);
// 并将新歌链接存放在缓存中以备后面使用
uni.setStorageSync('musiclink',res.data.data.url);
resolve(true);
}else{
reject(false)
}
},
fail:(err)=> {// 请求没得到响应
reject(false)
}
})
})
},
controlMusic(){
// 点击了播放就会给musicPlay置true
if(this.musicPlay){
if(this.isNewMusic){// 如果是新歌,那就给新地址作为歌曲资源
this.bgAudioManager.src=this.musicData.url;
this.bgAudioManager.title=this.musicData.name;
// 当前的歌曲资源一旦赋值出去就会播放也就成为了在播歌不再是新歌
this.isNewMusic=false;
}else{
// 获取缓存链接信息
let musiclink=uni.getStorageSync('musiclink');
if(musiclink==this.musicData.url){// 还是原来的歌,从暂停到播放,调play()
this.bgAudioManager.play();
}else{// 不是原来的歌了,从头播放,重新赋值新的歌曲资源
this.bgAudioManager.src=this.musicData.url;
this.bgAudioManager.title=this.musicData.name;
}
}
}else{// 点击了暂停就会给musicPlay置false
this.bgAudioManager.pause();
}
}
如果涉及到切歌得注意前面那个flag
// 切歌
nextMusic(){
// 停止当前歌曲
this.bgAudioManager.stop();
this.musicPlay=false;
// 切歌后缓存和this.musicData.url都是一样的,所以这里要当作和初始获取的状态一样,否则走controlMusic不能播放
this.isNewMusic=true;
// 获取新歌资源---将getMusic作为异步避免这里切歌后总是播放上一次请求的歌曲
this.getMusic().then(()=>{
// 自动播放新切的歌
this.controlMusic();
}).catch(()=>{
uni.showToast({
title:'音乐获取失败...',
duration:2000,
icon:"none"
})
})
},