第1次录音点击结束录音后,再点击开始录音然后点击结束 onStop录音停止事件会执行2次,以此类推
- 发布:2024-09-27 10:39
- 更新:2024-09-27 11:03
- 阅读:150
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: Windows 11 专业版
HBuilderX类型: 正式
HBuilderX版本号: 4.28
手机系统: Android
手机系统版本号: Android 15
手机厂商: 华为
手机机型: 华为P40pro
页面类型: vue
vue版本: vue2
打包方式: 云端
项目创建方式: HBuilderX
操作步骤:
预期结果:
每次点击结束录音onStop只执行一次
每次点击结束录音onStop只执行一次
实际结果:
第1次录音点击结束录音后,再点击开始录音然后点击结束 onStop录音停止事件会执行2次,以此类推
第1次录音点击结束录音后,再点击开始录音然后点击结束 onStop录音停止事件会执行2次,以此类推
bug描述:
<template>
<view class="real_time_shouting container">
<!-- <NavTitle title="实时喊话"></NavTitle> -->
<view class="main_cont">
<view class="volume_level">
<view class="left">音量大小</view>
<!-- <view class="center">
<uni-easyinput :clearable="false" v-model="volume" :inputBorder="false" type="number" placeholder="请输入音量大小"></uni-easyinput>
</view> -->
<view class="right">
<view class="icon">
<uni-icons @click="volumeMinusClick()" type="minus" size="21"></uni-icons>
</view>
<view class="num">{{volume?volume:0}}</view>
<view class="icon">
<uni-icons @click="volumePlusClick()" type="plus" size="21"></uni-icons>
</view>
</view>
</view>
<view class="info">
<view class="name">喊话时长</view>
<view class="time">{{formatTime(timesNum)}}</view>
</view>
</view>
<view class="btn_op">
<view class="a" :class="isRealTime?'active':''" @click="realTime()">{{!isRealTime? '开始喊话':'结束喊话'}}</view>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import {
ACCESS_TOKEN,
USER_NAME,
USER_INFO
} from "@/common/constants"
import {
getAction,
postAction,
httpFormDataAction
} from "@/api/mamage.js"
import {
success,
error
} from "@/util/message.js"
import {
getServerInfo
} from "@/util/getServer.js"
import {
formatTime,
randomString
} from "@/util/validate.js"
import {uploadFile} from "@/api/api.js"
const recorderManager = uni.getRecorderManager()
const innerAudioContext = uni.createInnerAudioContext()
innerAudioContext.autoplay = true
export default {
name: 'realTimeShouting',
components: {
// NavTitle
},
data() {
return {
towerInfo: null, // 监测塔相关信息
objurl: {
send: `/hytec/ipsound/appRealTimeVoiceByTower`,
},
volume: 70, // 音量
timesNum: 0, // 喊话时长
isRealTime: false, // 是否正在喊话
timeTimer: null, // 喊话时间定时器
}
},
onLoad(option) {
// 接收传递过来的数据
this.towerInfo = JSON.parse(decodeURIComponent(option.info))
// this.startRecord()
this.lintenStop()
},
onHide() {
// 停止
this.stopPushAndClearTimer()
},
methods: {
lintenStop() {
console.log("初始化监听结束---------------")
let that = this;
recorderManager.onStop(function(res) {
console.log("res结束----", res)
innerAudioContext.src = res.tempFilePath
innerAudioContext.onCanplay(()=>{
console.log("innerAudioContext.duration",innerAudioContext.duration)
if(innerAudioContext.duration<1){
return
}
let obj = {
tempFilePath:res.tempFilePath,
duration:innerAudioContext.duration
}
// 发送
that.sendVoice(obj)
})
});
},
// 音量减小
volumeMinusClick() {
let that = this
if (that.volume <= 1) {
that.$refs.uToast.show(error('音量不能小于0!'))
that.volume = 0
return
}
that.volume--
},
// 音量加大
volumePlusClick() {
let that = this
if (that.volume >= 100) {
that.volume = 100
that.$refs.uToast.show(error('音量不能大于100!'))
return
}
that.volume++
},
startRecord() {
console.log('开始录音');
recorderManager.start();
this.$nextTick(() => {
this.endRecord()
})
},
endRecord() {
console.log('录音结束');
recorderManager.stop();
},
formatTime,
// 开始喊话
realTime() {
let that = this
if (!that.isRealTime) {
// 调用开始喊话接口
that.audioStart()
} else {
// 停止和关闭计时器
that.stopPushAndClearTimer()
}
},
// 停止推流和关闭计时器
stopPushAndClearTimer() {
let that = this
recorderManager.stop();
that.isRealTime = false
if (that.timeTimer) {
// 清理计数定时器
clearInterval(that.timeTimer)
that.timeTimer = null
}
that.timesNum = 0
},
// 开始喊话
audioStart() {
let that = this
if (that.volume < 0) {
that.$refs.uToast.show(error("音量不能小于0!"))
return
}
if (that.volume > 100) {
that.$refs.uToast.show(error("音量不能大于100!"))
return
}
that.$refs.uToast.show(success("请开始喊话!"))
recorderManager.start({
duration: 10 * 60 * 1000
});
that.isRealTime = true
that.timeTimer = setInterval(() => {
that.setTimeTimer()
}, 1 * 1000)
},
// 发送
async sendVoice(obj) {
let that = this
console.log("iooooooo",obj)
if (!obj || !obj.tempFilePath) {
that.$refs.uToast.show(error("请先录音!"))
return
}
let uploadFileInfo = await uploadFile("",obj.tempFilePath)
if(uploadFileInfo.success && uploadFileInfo.message){
let params = {
'towerId': that.towerInfo.id,
'voiceTime': obj.duration?(obj.duration+1).toFixed(0):0,
'volume': that.volume,
'fileUrl':uploadFileInfo.message
}
httpFormDataAction(that.objurl.send,params).then(res=>{
if(res.success){
that.$refs.uToast.show(success(res.message))
}else{
that.$refs.uToast.show(error(res.message))
}
})
}
},
// 开始计时
setTimeTimer() {
let that = this
that.timesNum += 1
},
}
}
</script>
<style lang="scss" scoped>
.real_time_shouting {
.main_cont {
padding: 0 24rpx;
.cameras {
height: 396rpx;
border-radius: 20rpx;
width: 100%;
overflow: hidden;
margin-top: 24rpx;
}
.volume_level {
display: flex;
justify-content: space-between;
margin-top: 22rpx;
background: #fff;
padding: 0 30rpx;
height: 88rpx;
border-radius: 12rpx;
.left {
font-size: 24rpx;
color: #141C3B;
font-weight: bold;
display: flex;
align-items: center;
}
.right {
display: flex;
align-items: center;
.num {
margin: 0 15rpx;
}
}
}
.info {
margin-top: 232rpx;
text-align: center;
color: #141C3B;
.name {
font-size: 24rpx;
}
.time {
margin-top: 35rpx;
font-weight: bold;
}
}
.btn_a {
width: 258rpx;
height: 258rpx;
margin: 0 auto;
position: relative;
.circle {
border: 1px solid red;
position: absolute;
border-radius: 50%;
opacity: 0;
}
.content {
width: 164rpx;
height: 164rpx;
background: linear-gradient(0deg, #0F8C98 0%, #13A5B3 100%);
border-radius: 50%;
text-align: center;
margin: 0 auto;
margin-top: 47rpx;
position: relative;
z-index: 2;
image {
width: 60rpx;
height: 100rpx;
margin: 0 auto;
margin-top: 32rpx;
}
}
}
.ripple {
.circle {
width: calc(100% - 6rpx);
/* 减去边框的大小 */
height: calc(100% - 6rpx);
/* 减去边框的大小 */
border: 6rpx solid #13A5B3;
}
.circle:first-child {
animation: circle-opacity 2s infinite;
}
.circle:nth-child(2) {
animation: circle-opacity 2s infinite;
animation-delay: .3s;
}
.circle:nth-child(3) {
animation: circle-opacity 2s infinite;
animation-delay: .6s;
}
}
}
.btn_op {
height: 124rpx;
background: #FFFFFF;
box-shadow: 0rpx -3rpx 16rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 30rpx 30rpx 0rpx 0rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
.a {
height: 80rpx;
background: #1577F1;
border-radius: 20rpx;
text-align: center;
line-height: 80rpx;
font-size: 28rpx;
font-weight: bold;
color: #fff;
width: 90%;
margin: 0 auto;
margin-top: 26rpx;
}
.active {
background: #f56c6c !important;
}
}
}
@keyframes circle-opacity {
from {
opacity: 1;
transform: scale(0);
}
to {
opacity: 0;
transform: scale(1);
}
}
</style>
<style>
page {
width: 100%;
height: 100vh;
background: #F5F6F7;
}
</style>
1 个回复
小嗨嗨 (作者)
解决了是 把 innerAudioContext.onCanplay 写在了结束录音里面了,导致多次触发后面的逻辑