腾讯语音实时识别-vue项目-pc端

文章介绍了如何在JavaScript中使用腾讯提供的WebAudioSpeechRecognizerSDK进行语音识别,包括设置参数、鉴权函数和实时识别事件处理。开发者可以配置参数以适应不同的业务需求,并处理识别开始、变化、结束和错误情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用:

import { signCallback } from './vioce/asrauthentication'
import './vioce/config'
import './vioce/speechrecognizer'

data中

webAudioSpeechRecognizer: '',
 created() {
        // // console.log('window', window);
        const params = {
            signCallback: signCallback, // 鉴权函数
            // 用户参数
            secretid: config.secretId,
            appid: config.appId,
            // 实时识别接口参数
            engine_model_type: '16k_zh', // 因为内置WebRecorder采样16k的数据,所以参数 engineModelType 需要选择16k的引擎,为 '16k_zh'
            // 以下为非必填参数,可跟据业务自行修改
            voice_format: 1,
            hotword_id: '08003a00000000000000000000000000',
            needvad: 1,
            filter_dirty: 1,
            filter_modal: 2,
            filter_punc: 0,
            convert_num_mode: 1,
            word_info: 2
        }
        this.webAudioSpeechRecognizer = new WebAudioSpeechRecognizer(params);
    },

点击开始

opens() {
            const params = {
                signCallback: signCallback, // 鉴权函数
                // 用户参数
                secretid: config.secretId,
                appid: config.appId,
                // 实时识别接口参数
                engine_model_type: '16k_zh', // 因为内置WebRecorder采样16k的数据,所以参数 engineModelType 需要选择16k的引擎,为 '16k_zh'
                // 以下为非必填参数,可跟据业务自行修改
                voice_format: 1,
                hotword_id: '08003a00000000000000000000000000',
                needvad: 1,
                filter_dirty: 1,
                filter_modal: 2,
                filter_punc: 0,
                convert_num_mode: 1,
                word_info: 2
            }
            this.webAudioSpeechRecognizer = new WebAudioSpeechRecognizer(params);

            this.countdown = 0
            this.sendCode()

            this.voicebool = true

            // 开始识别
            this.webAudioSpeechRecognizer.OnRecognitionStart = (res) => {
                // console.log('开始识别', res);
            };
            // 一句话开始
            this.webAudioSpeechRecognizer.OnSentenceBegin = (res) => {
                // // console.log('一句话开始', res);
            };
            // 识别变化时
            this.webAudioSpeechRecognizer.OnRecognitionResultChange = (res) => {
                this.areaDom = `${this.resultText}${res.result.voice_text_str}`;
                // console.log('识别变化时', res.result.voice_text_str);

            };
            // 一句话结束
            this.webAudioSpeechRecognizer.OnSentenceEnd = (res) => {
                // console.log('一句话结束', res.result.voice_text_str);
                this.resultText += res.result.voice_text_str;
                this.areaDom = this.resultText
            };
            // 识别结束
            this.webAudioSpeechRecognizer.OnRecognitionComplete = (res) => {
                // // console.log('识别结束', res);
            };
            // 识别错误
            this.webAudioSpeechRecognizer.OnError = (res) => {
                // // console.log('识别失败-------------', res)
                this.$message({
                    message: '录音失败',
                    type: 'error'
                });
            };
            this.webAudioSpeechRecognizer.start();


            // console.log('===================================', this.resultText);
        },

点击结束

close() {
            this.webAudioSpeechRecognizer.stop();
            this.voicebool = false
        }

完整代码

<template>
    <div class="panel">
        <!-- {{ resultText }} -->
        <div class="panel-top">
            <div class="left" v-if="voicebool == false">
                <div class="btnbox" @click="opens()" v-if="!this.flag">
                    <img class="imgclass" src="../../assets/aigc/语音@2x.png" alt="">
                </div>
                <div class="btnbox" @click="opens()" style="background:#ebeef5" v-if="this.flag">
                    <img class="imgclass" src="../../assets/aigc/语音@2x.png" alt="">
                </div>
                <span class="spanclass">点击麦克风开始录音,请对我说你想说的话,可以在右侧看到识别结果</span>
            </div>

            <div class="left" v-if="voicebool == true">
                <!-- <AaaContent /> -->
                <div style="margin-top: 40px;margin-bottom: 20px;">00:
                    <span v-if="countdown < 10">0{{ countdown }}</span>
                    <span v-if="countdown >= 10">{{ countdown }}</span> /
                    00:{{ time }}
                </div>
                <!-- <br /> -->
                <el-button type="primary" @click="close()">结束识别</el-button>
            </div>


            <div class="center">
                <div class="inputbox">
                    <textarea maxlength="-1" rows="9" class="c_input" v-model="areaDom" auto-height="true"
                        placeholder="问我任何问题...(shift + Enter 换行 , 按下 Enter 发送)" @keyup.enter="sendMsg"></textarea>
                </div>

                <div class="right">
                    <div class="send">
                        <el-button v-if="!this.flag" @click="sendMsgfun">发送</el-button>
                        <el-button v-if="this.flag">回复中</el-button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import { signCallback } from './vioce/asrauthentication'
import './vioce/config'
import './vioce/speechrecognizer'

export default {
    data() {
        return {
            content: '',
            flag: false,
            webAudioSpeechRecognizer: '',
            voicebool: false,
            resultText: '',
            resultText2: '',
            time: '30',
            countdown: '0',
            areaDom: '',
            resultbool: false
        }
    },
    created() {
        // // console.log('window', window);
        const params = {
            signCallback: signCallback, // 鉴权函数
            // 用户参数
            secretid: config.secretId,
            appid: config.appId,
            // 实时识别接口参数
            engine_model_type: '16k_zh', // 因为内置WebRecorder采样16k的数据,所以参数 engineModelType 需要选择16k的引擎,为 '16k_zh'
            // 以下为非必填参数,可跟据业务自行修改
            voice_format: 1,
            hotword_id: '08003a00000000000000000000000000',
            needvad: 1,
            filter_dirty: 1,
            filter_modal: 2,
            filter_punc: 0,
            convert_num_mode: 1,
            word_info: 2
        }
        this.webAudioSpeechRecognizer = new WebAudioSpeechRecognizer(params);
    },
    methods: {
        sendCode() {
            // 开启定时
            this.clearTimer();
            this.timer = setInterval(() => {
                this.countdown++;
                // 停止定时器
                if (this.countdown == 30) {
                    this.clearTimer();
                    this.close();
                    this.countdown = 0
                }
            }, 1000)
        },
        clearTimer() {
            //清除定时器
            clearInterval(this.timer);
            this.timer = null;
        },
        sendMsg(e) {
            if (!e.shiftKey && e.keyCode == 13) {
                e.cancelBubble = true; //ie阻止冒泡行为
                e.stopPropagation(); //Firefox阻止冒泡行为
                e.preventDefault(); //取消事件的默认动作*换行

                this.flag = true
                this.$emit("sendProblem", this.areaDom)
            }
        },
        sendMsgfun() {
            this.flag = true
            this.$emit("sendProblem", this.areaDom)
        },
        clearMag() {
            // this.resultText = ''
            this.flag = false
        },
        opens() {
            const params = {
                signCallback: signCallback, // 鉴权函数
                // 用户参数
                secretid: config.secretId,
                appid: config.appId,
                // 实时识别接口参数
                engine_model_type: '16k_zh', // 因为内置WebRecorder采样16k的数据,所以参数 engineModelType 需要选择16k的引擎,为 '16k_zh'
                // 以下为非必填参数,可跟据业务自行修改
                voice_format: 1,
                hotword_id: '08003a00000000000000000000000000',
                needvad: 1,
                filter_dirty: 1,
                filter_modal: 2,
                filter_punc: 0,
                convert_num_mode: 1,
                word_info: 2
            }
            this.webAudioSpeechRecognizer = new WebAudioSpeechRecognizer(params);

            this.countdown = 0
            this.sendCode()

            this.voicebool = true

            // 开始识别
            this.webAudioSpeechRecognizer.OnRecognitionStart = (res) => {
                // console.log('开始识别', res);
            };
            // 一句话开始
            this.webAudioSpeechRecognizer.OnSentenceBegin = (res) => {
                // // console.log('一句话开始', res);
            };
            // 识别变化时
            this.webAudioSpeechRecognizer.OnRecognitionResultChange = (res) => {
                this.areaDom = `${this.resultText}${res.result.voice_text_str}`;
                // console.log('识别变化时', res.result.voice_text_str);

            };
            // 一句话结束
            this.webAudioSpeechRecognizer.OnSentenceEnd = (res) => {
                // console.log('一句话结束', res.result.voice_text_str);
                this.resultText += res.result.voice_text_str;
                this.areaDom = this.resultText
            };
            // 识别结束
            this.webAudioSpeechRecognizer.OnRecognitionComplete = (res) => {
                // // console.log('识别结束', res);
            };
            // 识别错误
            this.webAudioSpeechRecognizer.OnError = (res) => {
                // // console.log('识别失败-------------', res)
                this.$message({
                    message: '录音失败',
                    type: 'error'
                });
            };
            this.webAudioSpeechRecognizer.start();


            // console.log('===================================', this.resultText);
        },
        close() {
            this.webAudioSpeechRecognizer.stop();
            this.voicebool = false

            if (this.countdown == 30) {
                // alert('123')
                this.$message({
                    message: '录音结束',
                    type: 'warning'
                });

                this.countdown = 0
            }

        }
    }
}
</script>

<style lang="scss" scoped>
.left {
    width: 300px;
    text-align: -webkit-center;
}

.spanclass {
    width: 300px;
    display: block;
    padding: 15px;
    color: #7a8cac;
}

.btnbox {
    width: 54px;
    background-color: #1677FF;
    height: 54px;
    border-radius: 50%;
    margin-top: 20px;

    .imgclass {
        width: 46px;
        height: 28px;
        margin-top: 13px;
    }
}

.inputbox {
    margin-left: 2%;
}

textarea::-webkit-input-placeholder {
    /* WebKit browsers */
    color: #7a8cac;
}

textarea:-moz-placeholder {
    /* Mozilla Firefox 4 to 18 */
    color: #7a8cac;
}

textarea::-moz-placeholder {
    /* Mozilla Firefox 19+ */
    color: #7a8cac;
}

textarea::-ms-input-placeholder {
    /* Internet Explorer 10+ */
    color: #7a8cac;
}

.c_input {
    width: 92%;
    resize: none;
    background: #fff;
    border-style: none;
    text-indent: 30px;
    outline: none;
    opacity: 1;
    font-size: 14px;
    border-radius: 10px;
    font-weight: 400;
    color: #7a8cac;
    /* margin-top: 1%; */
    margin-bottom: -1%;
}

.panel {
    position: fixed;
    z-index: 1100;
    left: 0;
    right: 0;
    width: 100vw;
    bottom: 0px;
    cursor: pointer;
    padding-bottom: env(safe-area-inset-bottom);

    .panel-top {
        width: 100%;
        display: flex;
        overflow: hidden;

        .left {


            .sound {
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: flex-end;

                image {
                    width: 70%;
                    height: 70%;
                    margin-bottom: 24px;
                }
            }
        }

        .center {
            /* flex: 1; */
            position: relative;
            background: #fff;
            width: 78%;
            margin-top: 1%;

            .s_btn {
                height: 80px;
                font-size: 32px;
                display: flex;
                justify-content: center;
                align-items: center;
                color: #b3b3b3;
            }

            .touch {
                background: #43d305;
                color: white;
            }
        }

        .right {
            display: flex;
            position: absolute;
            top: 70%;
            right: -3%;

            .emoji {
                width: 120px;
                display: flex;
                justify-content: center;
                align-items: flex-end;
                margin-right: 4px;

                image {
                    width: 70%;
                    height: 70%;
                    margin-bottom: 24px;
                }
            }

            .add {
                width: 80px;
                display: flex;
                justify-content: center;
                margin-right: 4px;
                align-items: flex-end;

                image {
                    width: 70%;
                    height: 70%;
                    margin-bottom: 24px;
                }
            }

            .send {
                width: 160px;
                display: flex;
                justify-content: center;
                align-items: flex-end;

                .btnbox {
                    position: relative;
                    top: -25%;
                }
            }
        }
    }

    .panel-bottom {
        background: #ecedee;
        height: 0px;
        overflow: hidden;

        .bottom-box {
            margin: 30px;
            width: calc(100vw - 60px);
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;

            .module {
                width: 25%;
                display: flex;
                flex-wrap: wrap;
                justify-content: center;
                align-items: center;
                margin-bottom: 30px;

                .module-item {
                    width: 100px;
                    height: 100px;
                    border-radius: 10px;
                    background: white;
                    display: flex;
                    justify-content: center;
                    align-items: center;

                    image {
                        width: 60%;
                        height: 60%;
                    }

                    .hongbao {
                        width: 70%;
                        height: 70%;
                    }
                }

                .module-title {
                    width: 100%;
                    font-size: 24px;
                    color: rgba(39, 40, 50, 0.5);
                    height: 60px;
                    line-height: 60px;
                    text-align: center;
                }
            }

            .emoji {
                margin-top: 30px;
            }
        }
    }
}
</style>

1.asrauthentication.js

/** 获取签名 start */

function toUint8Array(wordArray) {
  // Shortcuts
  const words = wordArray.words;
  const sigBytes = wordArray.sigBytes;

  // Convert
  const u8 = new Uint8Array(sigBytes);
  for (let i = 0; i < sigBytes; i++) {
    u8[i] = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  }
  return u8;
}

function Uint8ArrayToString(fileData){
  let dataString = '';
  for (let i = 0; i < fileData.length; i++) {
    dataString += String.fromCharCode(fileData[i]);
  }
  return dataString;
}
// 签名函数示例
export function signCallback(signStr) {
  const secretKey = config.secretKey;
  const hash = window.CryptoJSTest.HmacSHA1(signStr, secretKey);
  const bytes = Uint8ArrayToString(toUint8Array(hash));
  return window.btoa(bytes);
}

/** 获取签名 end */

2.config.js

let config = {
  secretKey: 'xxxxx',
  secretId: 'xxxxxxx',
  appId: xxxxxxxx,
}
window.config = config

在腾讯语音识别中购买的sdk

3.speechrecognizer.js

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值