project/pages/common/audioPay.vue

334 lines
7.5 KiB
Vue
Raw Normal View History

2024-07-14 15:48:34 +08:00
<template>
<!-- 音频播放器组件 -->
<view v-if='url' class='flex audio'>
<view class='ml-3'>{{getTime(Math.round(currentTime))}}</view>
<view class='flex-1'>
<slider @change='changeAudio' @changing='changeing' :activeColor='activeColor' :min='0'
:max='duration ? duration.toFixed(0) : "00:00"' :value='currentTime != 0 ? currentTime.toFixed(0) : 0'
:step='0.1'></slider>
</view>
<view class='ml-3'>{{getTime(Math.round(totalDuration))}}</view>
<view class='mr-3' @click='start(audioId)'>
<image src='@/static/images/playicon.png' class='icon' v-show='!status'></image>
<image src='@/static/images/stopicon.png' class='icon' v-show='status'></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
context: null,
currentTime: 0,
duration: 100,
status: false,
totalDuration: 0,
bgAudioManager: null,
useBackgroundAudioManager: false,
flag: true,
// 是否只能播放一次
isPlay: false,
aid:'',
};
},
props: {
url: String,
activeColor: {
type: String,
default: '#0E7EFC'
},
audioId: [String, Number],
isChecked: {
type: Boolean,
default: false
}
},
watch: {
url(newValue, oldValue) {
this.url = newValue
if(newValue != oldValue){
console.log(123);
this.context.stop();
this.status = false
}
this.currentTime = 0
this.createAudio()
},
isChecked(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
if (newValue == false) {
this.isPlay = false
}
},
audioId(newValue, oldValue) {
console.log(newValue);
console.log(oldValue);
},
},
created() {
this.createAudio()
},
destroyed() {
this.context.stop();
},
methods: {
// 初始化
createAudio() {
this.bgAudioManager = uni.getBackgroundAudioManager();
this.context = uni.createInnerAudioContext();
console.log(this.url);
this.context.src = this.url;
this.context.sessionCategory = 'soloAmbient'
// uni.createInnerAudioContext事件听
this.onTimeUpdate();
this.onCanplay();
this.onEnded();
this.onErrorHandle();
// uni.getBackgroundAudioManager事件监听
this.onBgCanplay();
this.onBgTimeUpdate();
this.onBgEnded();
this.onBgStop();
uni.$on('stop', (id) => {
if(this.aid != id){
this.currentTime = 0
}
this.aid = id
if (id && id != this.audioId) {
this.context.stop();
this.status = false;
} else if (!id) {
this.context.stop();
this.status = false;
}
});
uni.$on('BackgroundAudioStop', (id) => {
if (id && id != this.audioId) {
this.bgAudioManager.stop();
this.status = false;
} else if (!id) {
this.bgAudioManager.stop();
this.status = false;
}
});
// uni.setInnerAudioOption({
// obeyMuteSwitch: false
// });
},
/**
* uni.getBackgroundAudioManager事件监听
*/
onBgCanplay() {
this.bgAudioManager.onCanplay(() => {
setTimeout(() => {
this.duration = this.bgAudioManager.duration;
this.totalDuration = this.bgAudioManager.duration;
console.log(this.duration, this.totalDuration);
}, 1000);
});
},
onBgTimeUpdate() {
this.bgAudioManager.onTimeUpdate(() => {
// 判定是否为无穷大,且动态赋值
if (!Number.isFinite(this.bgAudioManager.duration)) {
this.duration = this.bgAudioManager.currentTime + 10;
this.currentTime = this.bgAudioManager.currentTime;
} else {
this.duration = this.bgAudioManager.duration;
this.currentTime = this.bgAudioManager.currentTime;
}
});
},
// 自然播放结束
onBgEnded() {
this.bgAudioManager.onEnded(() => {
this.status = false;
this.currentTime = 0;
this.flag = true;
console.log('onBgEnded');
});
},
// 音频停止
onBgStop() {
console.log(1444);
this.bgAudioManager.onStop(() => {
this.status = false;
this.currentTime = 0;
this.flag = true;
console.log('onBgStop');
});
},
/**
* uni.createInnerAudioContext事件听
*/
start(id) { //点击播放
// 是否只能播放一次
if (this.isPlay == false) {
if (this.useBackgroundAudioManager) {
console.log(this.bgAudioManager.src);
if (this.flag) {
this.bgAudioManager.src = this.url;
this.flag = false;
}
this.duration = this.bgAudioManager.duration;
console.log(21222, this.duration);
if (this.status) {
this.bgAudioManager.pause();
this.status = !this.status;
} else {
// uni.$emit('BackgroundAudioStop',id);
this.bgAudioManager.play();
this.status = !this.status;
}
return;
}
if (this.status) {
this.context.pause();
this.status = !this.status;
} else {
uni.$emit('stop', id);
this.context.play();
this.status = !this.status;
}
} else {
uni.showToast({
title: "该音频只能播放一次",
duration: 2000,
icon: 'none'
});
}
},
onCanplay() { //进入可播放状态
this.context.onCanplay(() => {
this.context.duration;
setTimeout(() => {
this.duration = this.context.duration;
this.totalDuration = this.context.duration;
}, 1000);
});
},
onTimeUpdate() { //音频播放进度
this.context.onTimeUpdate(() => {
// console.log('onTimeUpdate');
// console.log(this.context.duration);
if (!Number.isFinite(this.context.duration)) {
this.duration = this.context.currentTime + 10;
this.currentTime = this.context.currentTime;
} else {
this.duration = this.context.duration;
this.currentTime = this.context.currentTime;
}
});
},
onEnded() { //播放结束
this.context.onEnded(() => {
this.status = false;
this.currentTime = 0;
console.log(233);
console.log(this.isChecked);
this.isPlay = this.isChecked
});
},
onErrorHandle() {
this.context.onError((res) => {
console.log(res.errMsg);
console.log(res.errCode);
this.useBackgroundAudioManager = true;
this.bgAudioManager.title = '报告回听';
console.log('bgAudioManager.duration', this.bgAudioManager.duration);
});
},
changeAudio(e) {
let paused = this.context.paused;
this.context.pause();
this.context.seek(e.detail.value)
if(!paused) {
this.context.play();
}
},
changeing(e) {
console.log(this.context);
this.currentTime = e.detail.value
// this.start()
},
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;
}
},
// 销毁
destroy() {
this.bgAudioManager.stop();
this.context.stop();
this.context.destroy();
this.status = false;
},
}
};
</script>
<style lang="scss">
/deep/uni-slider .uni-slider-handle {
width: 15px;
height: 15px;
margin-left: -8px;
margin-top: -8px;
}
/deep/uni-slider .uni-slider-thumb {
width: 15px !important;
height: 15px !important;
margin-left: -8px !important;
margin-top: -8px !important;
}
.audio {
background: #f4f4f4;
padding: 20rpx;
border-radius: 10rpx;
}
.icon {
width: 60rpx;
height: 60rpx;
}
.flex {
display: flex;
flex-direction: row;
justify-content: between;
align-items: center;
width: 100%;
}
.flex-1 {
flex: 1;
}
.mr-3 {
margin-left: 10rpx;
}
.ml-3 {
color: #ccc;
}
</style>