小嗨嗨
小嗨嗨
  • 发布:2024-09-27 10:39
  • 更新:2024-09-27 11:03
  • 阅读:150

【报Bug】 uni.getRecorderManager onStop录音停止事件,执行多次,第1次录音执行1次,第2次录音执行2次,以此类推

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: Windows 11 专业版

HBuilderX类型: 正式

HBuilderX版本号: 4.28

手机系统: Android

手机系统版本号: Android 15

手机厂商: 华为

手机机型: 华为P40pro

页面类型: vue

vue版本: vue2

打包方式: 云端

项目创建方式: HBuilderX

操作步骤:

第1次录音点击结束录音后,再点击开始录音然后点击结束 onStop录音停止事件会执行2次,以此类推

预期结果:

每次点击结束录音onStop只执行一次

实际结果:

第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>
2024-09-27 10:39 负责人:无 分享
已邀请:
小嗨嗨

小嗨嗨 (作者)

解决了是 把 innerAudioContext.onCanplay 写在了结束录音里面了,导致多次触发后面的逻辑

要回复问题请先登录注册