UNIAPP调用讯飞语音评测API

1、历经千辛万苦,UNIAPP调用评测API终于完成,在此做下总结下:首先看效果!

UNIAPP调用讯飞语音评测API_第1张图片

2、实现第1步,首先是鉴权,用到的CryptoJS等工具都可以从讯飞和uniapp官方获取
import * as base64 from "base-64"
import CryptoJS from '../../static/crypto-js/crypto-js.js'
import parser from '../../static/fast-xml-parser/src/parser'
import * as utf8 from "utf8"

getWebSocketUrl() {
                return new Promise((resolve, reject) => {
                    // 请求地址根据语种不同变化
                    var url = "wss://ise-api.xfyun.cn/v2/open-ise";
                    var host = "ise-api.xfyun.cn";
                    var apiKeyName = "api_key";
                    var date = new Date().toGMTString();
                    var algorithm = "hmac-sha256";
                    var headers = "host date request-line";
                    var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/open-ise HTTP/1.1`;
                    var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, this.APISecret);
                    var signature = CryptoJS.enc.Base64.stringify(signatureSha);
                    var authorizationOrigin =
                        `${apiKeyName}="${this.APIKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
                    var authorization = base64.encode(authorizationOrigin);
                    url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;

                    // console.log(url)
                    resolve(url); // 主要是返回地址
                });
            },
3、实现第2不,构建websocket连接
data() {
            return {
                socketTask: {}, // 全局ws任务
                audioDataList: [], // 临时录音存储集合
                APPID: '',
                APISecret: '',
                APIKey: '',
                ent: 'cn_vip',
                category: 'read_sentence',
                TEXT: '\uFEFF' + '今天天气怎么样',
                wsLiveFlag: false,
                iseResult: '',
                iseFinalResult: '',
                speakMark: '开始评测录音',
                buttonGroup: [{
                    text: '开始评测录音',
                    backgroundColor: 'green',
                    color: '#fff'
                }, {
                    text: '停止评测录音',
                    backgroundColor: '#ffa200',
                    color: '#fff'
                }],
            };
        },

 -------------------------------------------------

async bulidSocketConnect() {
                let myUrl = await this.getWebSocketUrl();
                // myUrl = 'wss://wdfgdzx.top/ws_server/zs'
                // console.log(encodeURI(encodeURI(myUrl).replace(/\+/g, '%2B')))
                let realThis = this;
                this.socketTask = uni.connectSocket({
                    //url: encodeURI(encodeURI(myUrl).replace(/\+/g, '%2B')),
                    url: myUrl,
                    method: 'GET',
                    success: res => {
                        console.log(res, "ws成功连接...", myUrl)
                        realThis.wsLiveFlag = true;
                    }
                })
                realThis.socketTask.onError((res) => {
                    console.log("连接发生错误", res)
                })
                realThis.socketTask.onOpen((res) => {
                    console.info("wss的onOpen成功执行...", res)
                    // 第一帧..........................................
                    console.log('open成功...')
                    let params = {
                        common: {
                            app_id: realThis.APPID
                        },
                        business: {
                            category: realThis.category,
                            ent: realThis.ent, // 中文
                            rstcd: "utf8",
                            sub: 'ise',
                            tte: 'utf-8',
                            cmd: "ssb",
                            auf: 'audio/L16;rate=16000',
                            aue: 'raw',
                            text: realThis.TEXT,
                        },
                        data: {
                            status: 0,
                            data: "",
                            // data: uni.arrayBufferToBase64(audioData[0]),
                        },
                    };
                    console.log("发送第一帧...", params)
                    realThis.socketTask.send({ // 发送消息,,都用uni的官方版本
                        data: JSON.stringify(params),
                        success() {
                            console.log('第一帧发送成功')
                        }
                    });
                });

                // 接受到消息时
                realThis.socketTask.onMessage((res) => {
                    console.log('收到API返回的内容:', res.data);
                    realThis.iseResult = res.data;
                    let temp = JSON.parse(res.data)
                    // console.log(temp)
                    if (temp.code !== 0) {
                        console.log(`${temp.code}:${temp.message}`);
                        realThis.socketTask.close({
                            success(res) {
                                console.log('关闭成功', res)
                                realThis.wsLiveFlag = false;
                            },
                            fail(err) {
                                console.log('关闭失败', err)
                            }
                        })
                    }
                    if (temp.code === 0) {
                        if (res.data && temp.data.status === 2) {
                            const data = base64.decode(temp.data.data);
                            let decodeStr = utf8.decode(data);
                            console.log(temp)
                            console.log(decodeStr) // 打印完毕评测结果再关闭
                            realThis.iseFinalResult = decodeStr;
                            setTimeout(() => {
                                realThis.socketTask.close({
                                    success(res) {
                                        console.log('关闭成功', res)
                                    },
                                    fail(err) {
                                        console.log('关闭失败', err)
                                    }
                                })
                            }, 2000)
                        }
                    }
                })

            },
4、实现步骤3,不断的通过uniapp实时录音,发送音频给服务端API,点击结束录音发送最后一帧音频
buttonClick(e) { // 点击评测按钮
                if (e.content.text === "开始评测录音") {
                    this.speakMark = '正在评测,语音输入中...'
                    const realThis = this;
                    // 开始录音,初始化一些东西
                    const option = {
                        duration: 600000, // 录音的时长,单位 ms,最大值 600000(10 分钟)
                        sampleRate: 16000, // 采样率(pc不支持)
                        numberOfChannels: 1, // 录音通道数
                        // encodeBitRate: 48000, // 编码码率(默认就是48000)
                        frameSize: 1, // 指定帧大小,单位 KB。传入 frameSize 后,每录制指定帧大小的内容后,会回调录制的文件内容,不指定则不会回调。暂仅支持 mp3、pcm 格式。
                        format: "pcm", // 音频格式,默认是 aac
                    }
                    recorderManager.onStart(() => {
                        console.log("recorder start");
                    });
                    recorderManager.onFrameRecorded((res) => {
                        // frameBuffer    ArrayBuffer    录音分片结果数据。  isLastFrame    Boolean    当前帧是否正常录音结束前的最后一帧
                        const {
                            frameBuffer
                        } = res;
                        // console.log(frameBuffer) 这里把音频放到临时的集合中,方便保存为文件
                        if (frameBuffer) {
                            realThis.audioDataList.push(frameBuffer);
                            // 2、判断连接了,发送中间帧..........................................
                            if (realThis.wsLiveFlag) {
                                const params = {
                                    business: {
                                        cmd: "auw",
                                        aus: 2,
                                        aue: "raw"
                                    },
                                    data: {
                                        status: 1,
                                        encoding: "raw",
                                        data_type: 1,
                                        data: uni.arrayBufferToBase64(frameBuffer),
                                    },
                                };
                                console.log("发送中间帧", params, realThis.wsLiveFlag)
                                realThis.socketTask.send({
                                    data: JSON.stringify(params),
                                    success() {
                                        console.log('中间帧发送成功')
                                    },
                                    fail(res) {
                                        console.log('中间帧发送失败...', res)
                                    }
                                });
                            }
                        }
                    });
                    recorderManager.start(option); // 开始录音时,建立ws连接
                    this.bulidSocketConnect();
                    //setTimeout(this.bulidSocketConnect, 2000) //  main延迟2秒入口建立ws连接
                }
                if (e.content.text === "停止评测录音") {
                    this.speakMark = '开始评测录音'
                    // 3、发送最后一帧..........................................
                    const params = {
                        "business": {
                            "cmd": "auw",
                            "aus": 4,
                            "aue": "raw"
                        },
                        "data": {
                            "status": 2,
                            "encoding": "raw",
                            "data_type": 1,
                            "data": "",
                        }
                    };
                    this.socketTask.send({
                        data: JSON.stringify(params),
                        success(res) {
                            console.log('最后一帧发送成功...', res)
                        },
                        fail(res) {
                            console.log('最后一帧发送失败...', res)
                        }
                    });
                    console.log("发送最后一帧", params)
                    console.log('录音结束');
                    recorderManager.stop();
                }
            },

5、直接可运行的DMEO可以

你可能感兴趣的:(uni-app,语音识别)