场景
uniapp播放音频Uni.createInnerAudio方法在ios某些机型报错,为此使用uni.getBackgroundAudioManager方法来兼容。
直接上代码
<template>
<!-- 音频播放器组件 -->
<view>
<view v-if="audioUrl" class="flex justify-between align-center audio">
<view class="mr-3" @click="audioPlay(audioId)">
{{ isPlaying ? "点击暂停" : "点击播放" }}
<!-- <image src="@/static/daily-supervision/play.png" class="icon" v-show="!isPlaying"></image>
<image src="@/static/daily-supervision/pause.png" class="icon" v-show="isPlaying"></image> -->
</view>
<view class="flex-1">
<slider @change="changeAudio" :activeColor="activeColor" :min="0" :max="duration" :value="currentTime.toFixed(0)" :step="0.1"></slider>
</view>
<!-- <view class='ml-3'>{{getTime(Math.round(currentTime))}}</view> -->
<view class="ml-3">{{ getTime(Math.round(currentTime)) }}/{{ getTime(Math.round(duration)) }}</view>
</view>
</view>
</template>
<script>
let innerAudioContext = null;
let bgAudioManager = null;
export default {
data() {
return {
currentTime: 0,
duration: 0,
totalDuration: 0,
useBackgroundAudioManager: false,
isPlaying: false,
flag: true,
res: "",
autoPlay: false,
};
},
props: {
audioUrl: String,
activeColor: {
type: String,
default: "#0E7EFC",
},
autoPlay: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "暂无",
},
singer: {
type: String,
default: "暂无",
},
coverImgUrl: {
type: String,
default: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/music-a.png",
},
audioId: [String, Number],
},
created() {
this.innerAudioContextInit();
// this.backgroundAudioInit();
},
methods: {
innerAudioContextInit() {
if (innerAudioContext) return;
console.log("音频-innerAudioContextInit");
innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.src = this.audioUrl;
innerAudioContext.play();
this.onCanplay();
this.onPlay();
this.onTimeUpdate();
this.onEnded();
this.onErrorHandle();
uni.setInnerAudioOption({
obeyMuteSwitch: false,
});
// uni.$on("stop", (id) => {
// if (id && id != this.audioId) {
// innerAudioContext.stop();
// this.isPlaying = false;
// } else if (!id) {
// innerAudioContext.stop();
// this.isPlaying = false;
// }
// });
// uni.$on("BackgroundAudioStop", (id) => {
// if (id && id != this.audioId) {
// innerAudioContext.stop();
// this.isPlaying = false;
// } else if (!id) {
// innerAudioContext.stop();
// this.isPlaying = false;
// }
// });
},
backgroundAudioInit() {
if (bgAudioManager) return;
console.log("音频-backgroundAudioInit");
bgAudioManager = uni.getBackgroundAudioManager();
bgAudioManager.title = this.title;
bgAudioManager.singer = this.singer;
bgAudioManager.coverImgUrl = this.coverImgUrl;
bgAudioManager.src = this.audioUrl;
// if (this.autoPlay) {
// this.isPlaying = true;
// bgAudioManager.play();
// }
this.onBgCanplay();
this.onBgTimeUpdate();
this.onBgEnded();
this.onBgStop();
},
audioPlay(id) {
//点击播放
let audioId = id;
if (this.useBackgroundAudioManager) {
console.log(bgAudioManager, "bgAudioManager");
// if (this.flag) {
// bgAudioManager.src = this.audioUrl;
// this.flag = false;
// }
if (!bgAudioManager.src) {
bgAudioManager.title = "云南白药电子书";
bgAudioManager.singer = "暂无";
bgAudioManager.coverImgUrl = "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/music-a.png";
bgAudioManager.src = this.audioUrl;
}
if (!bgAudioManager.paused) {
bgAudioManager.pause();
} else {
bgAudioManager.play();
// uni.$emit('BackgroundAudioStop',id);
// if (!bgAudioManager.src) {
// // 解决暂停后播放从新开始播放bug
// bgAudioManager.src = this.audioUrl;
// } else {
// bgAudioManager.play();
// }
}
this.isPlaying = !this.isPlaying;
} else {
console.log(innerAudioContext, "innerAudioContext");
if (!innerAudioContext.paused) {
innerAudioContext.pause();
this.isPlaying = !this.isPlaying;
} else {
// uni.$emit("stop", id);
if (!innerAudioContext.src) {
// 解决暂停后播放从新开始播放bug
innerAudioContext.src = this.audioUrl;
} else {
innerAudioContext.play();
}
this.isPlaying = !this.isPlaying;
}
}
},
onPlay() {
innerAudioContext.onPlay(() => {
console.log("音频-onPlay-开始播放", innerAudioContext);
});
},
onCanplay() {
innerAudioContext.onCanplay(() => {
console.log("音频-onCanplay-可播放状态", innerAudioContext);
this.duration = innerAudioContext.duration;
this.totalDuration = innerAudioContext.duration;
});
},
onTimeUpdate() {
innerAudioContext.onTimeUpdate(() => {
if (!Number.isFinite(innerAudioContext.duration)) {
this.duration = innerAudioContext.currentTime + 10;
this.currentTime = innerAudioContext.currentTime;
} else {
this.duration = innerAudioContext.duration;
this.currentTime = innerAudioContext.currentTime;
}
});
},
onEnded() {
innerAudioContext.onEnded(() => {
console.log("音频-onEnded-播放结束");
this.isPlaying = false;
this.currentTime = 0;
innerAudioContext.src = this.audioUrl;
});
},
onErrorHandle() {
innerAudioContext.onError((res) => {
console.log("音频-onErrorHandle-播放失败");
this.res = JSON.stringify(res);
this.useBackgroundAudioManager = true;
// bgAudioManager.play();
this.backgroundAudioInit();
});
},
/**
* uni.getBackgroundAudioManager事件监听
*/
onBgCanplay() {
bgAudioManager.onCanplay(() => {
console.log("音频-onBgCanplay-背景可播放状态");
this.duration = bgAudioManager.duration;
this.totalDuration = bgAudioManager.duration;
if (!this.autoPlay) {
innerAudioContext.pause();
}
});
},
onBgTimeUpdate() {
bgAudioManager.onTimeUpdate(() => {
if (!Number.isFinite(bgAudioManager.duration)) {
this.duration = bgAudioManager.currentTime + 10;
this.currentTime = bgAudioManager.currentTime;
} else {
this.duration = bgAudioManager.duration;
this.currentTime = bgAudioManager.currentTime;
}
});
},
onBgEnded() {
bgAudioManager.onEnded(() => {
console.log("音频-onBgEnded-背景播放end");
this.isPlaying = false;
this.currentTime = 0;
this.flag = true;
});
},
onBgStop() {
bgAudioManager.onStop(() => {
console.log("音频-onBgStop-背景播放stop");
this.isPlaying = false;
this.currentTime = 0;
this.flag = true;
console.log("onBgStop");
});
},
changeAudio(e) {
let context = this.useBackgroundAudioManager ? bgAudioManager : innerAudioContext;
context.seek(e.detail.value);
},
getTime(time) {
let m = parseInt(time / 60);
let s = time % 60;
return this.towNum(m) + ":" + this.towNum(s);
},
towNum(num) {
if (num >= 10) {
return num;
} else {
return "0" + num;
}
},
},
beforeDestroy() {
if (innerAudioContext) innerAudioContext.destroy();
if (bgAudioManager) bgAudioManager.stop();
},
};
</script>
<style>
.audio {
background: #f4f4f4;
padding: 20rpx;
}
.icon {
width: 60rpx;
height: 60rpx;
}
.flex {
display: flex;
flex-direction: row;
}
.justify-between {
justify-content: between;
}
.align-center {
align-items: center;
}
.flex-1 {
flex: 1;
}
.ml-3 {
margin-left: 30rpx;
}
.mr-3 {
margin-right: 30rpx;
}
</style>
注意
- 音频必须使用标准map3格式
-
getBackgroundAudioManager方法必须设置title才能播放
- 注意页面销毁对getBackgroundAudioManager控制