1、歷經(jīng)千辛萬(wàn)苦,UNIAPP調(diào)用評(píng)測(cè)API終于完成,在此做下總結(jié)下:首先看效果!
2、實(shí)現(xiàn)第1步,首先是鑒權(quán),用到的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) => {
?? ??? ??? ??? ??? ?// 請(qǐng)求地址根據(jù)語(yǔ)種不同變化
?? ??? ??? ??? ??? ?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、實(shí)現(xiàn)第2不,構(gòu)建websocket連接
data() {
?? ??? ??? ?return {
?? ??? ??? ??? ?socketTask: {}, // 全局ws任務(wù)
?? ??? ??? ??? ?audioDataList: [], // 臨時(shí)錄音存儲(chǔ)集合
?? ??? ??? ??? ?APPID: '',
?? ??? ??? ??? ?APISecret: '',
?? ??? ??? ??? ?APIKey: '',
?? ??? ??? ??? ?ent: 'cn_vip',
?? ??? ??? ??? ?category: 'read_sentence',
?? ??? ??? ??? ?TEXT: '\uFEFF' + '今天天氣怎么樣',
?? ??? ??? ??? ?wsLiveFlag: false,
?? ??? ??? ??? ?iseResult: '',
?? ??? ??? ??? ?iseFinalResult: '',
?? ??? ??? ??? ?speakMark: '開始評(píng)測(cè)錄音',
?? ??? ??? ??? ?buttonGroup: [{
?? ??? ??? ??? ??? ?text: '開始評(píng)測(cè)錄音',
?? ??? ??? ??? ??? ?backgroundColor: 'green',
?? ??? ??? ??? ??? ?color: '#fff'
?? ??? ??? ??? ?}, {
?? ??? ??? ??? ??? ?text: '停止評(píng)測(cè)錄音',
?? ??? ??? ??? ??? ?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("連接發(fā)生錯(cuò)誤", res)
?? ??? ??? ??? ?})
?? ??? ??? ??? ?realThis.socketTask.onOpen((res) => {
?? ??? ??? ??? ??? ?console.info("wss的onOpen成功執(zhí)行...", 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("發(fā)送第一幀...", params)
?? ??? ??? ??? ??? ?realThis.socketTask.send({ // 發(fā)送消息,,都用uni的官方版本
?? ??? ??? ??? ??? ??? ?data: JSON.stringify(params),
?? ??? ??? ??? ??? ??? ?success() {
?? ??? ??? ??? ??? ??? ??? ?console.log('第一幀發(fā)送成功')
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?});
?? ??? ??? ??? ?});
?? ??? ??? ??? ?// 接受到消息時(shí)
?? ??? ??? ??? ?realThis.socketTask.onMessage((res) => {
?? ??? ??? ??? ??? ?console.log('收到API返回的內(nèi)容:', 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('關(guān)閉成功', res)
?? ??? ??? ??? ??? ??? ??? ??? ?realThis.wsLiveFlag = false;
?? ??? ??? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ??? ??? ?fail(err) {
?? ??? ??? ??? ??? ??? ??? ??? ?console.log('關(guān)閉失敗', 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) // 打印完畢評(píng)測(cè)結(jié)果再關(guān)閉
?? ??? ??? ??? ??? ??? ??? ?realThis.iseFinalResult = decodeStr;
?? ??? ??? ??? ??? ??? ??? ?setTimeout(() => {
?? ??? ??? ??? ??? ??? ??? ??? ?realThis.socketTask.close({
?? ??? ??? ??? ??? ??? ??? ??? ??? ?success(res) {
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?console.log('關(guān)閉成功', res)
?? ??? ??? ??? ??? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ??? ??? ??? ??? ?fail(err) {
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?console.log('關(guān)閉失敗', err)
?? ??? ??? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ??? ??? ?})
?? ??? ??? ??? ??? ??? ??? ?}, 2000)
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?})
?? ??? ??? ?},
4、實(shí)現(xiàn)步驟3,不斷的通過uniapp實(shí)時(shí)錄音,發(fā)送音頻給服務(wù)端API,點(diǎn)擊結(jié)束錄音發(fā)送最后一幀音頻
buttonClick(e) { // 點(diǎn)擊評(píng)測(cè)按鈕
?? ??? ??? ??? ?if (e.content.text === "開始評(píng)測(cè)錄音") {
?? ??? ??? ??? ??? ?this.speakMark = '正在評(píng)測(cè),語(yǔ)音輸入中...'
?? ??? ??? ??? ??? ?const realThis = this;
?? ??? ??? ??? ??? ?// 開始錄音,初始化一些東西
?? ??? ??? ??? ??? ?const option = {
?? ??? ??? ??? ??? ??? ?duration: 600000, // 錄音的時(shí)長(zhǎng),單位 ms,最大值 600000(10 分鐘)
?? ??? ??? ??? ??? ??? ?sampleRate: 16000, // 采樣率(pc不支持)
?? ??? ??? ??? ??? ??? ?numberOfChannels: 1, // 錄音通道數(shù)
?? ??? ??? ??? ??? ??? ?// encodeBitRate: 48000, // 編碼碼率(默認(rèn)就是48000)
?? ??? ??? ??? ??? ??? ?frameSize: 1, // 指定幀大小,單位 KB。傳入 frameSize 后,每錄制指定幀大小的內(nèi)容后,會(huì)回調(diào)錄制的文件內(nèi)容,不指定則不會(huì)回調(diào)。暫僅支持 mp3、pcm 格式。
?? ??? ??? ??? ??? ??? ?format: "pcm", // 音頻格式,默認(rèn)是 aac
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?recorderManager.onStart(() => {
?? ??? ??? ??? ??? ??? ?console.log("recorder start");
?? ??? ??? ??? ??? ?});
?? ??? ??? ??? ??? ?recorderManager.onFrameRecorded((res) => {
?? ??? ??? ??? ??? ??? ?// frameBuffer?? ?ArrayBuffer?? ?錄音分片結(jié)果數(shù)據(jù)。 ?isLastFrame?? ?Boolean?? ?當(dāng)前幀是否正常錄音結(jié)束前的最后一幀
?? ??? ??? ??? ??? ??? ?const {
?? ??? ??? ??? ??? ??? ??? ?frameBuffer
?? ??? ??? ??? ??? ??? ?} = res;
?? ??? ??? ??? ??? ??? ?// console.log(frameBuffer) 這里把音頻放到臨時(shí)的集合中,方便保存為文件
?? ??? ??? ??? ??? ??? ?if (frameBuffer) {
?? ??? ??? ??? ??? ??? ??? ?realThis.audioDataList.push(frameBuffer);
?? ??? ??? ??? ??? ??? ??? ?// 2、判斷連接了,發(fā)送中間幀..........................................
?? ??? ??? ??? ??? ??? ??? ?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("發(fā)送中間幀", params, realThis.wsLiveFlag)
?? ??? ??? ??? ??? ??? ??? ??? ?realThis.socketTask.send({
?? ??? ??? ??? ??? ??? ??? ??? ??? ?data: JSON.stringify(params),
?? ??? ??? ??? ??? ??? ??? ??? ??? ?success() {
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?console.log('中間幀發(fā)送成功')
?? ??? ??? ??? ??? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ??? ??? ??? ??? ?fail(res) {
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?console.log('中間幀發(fā)送失敗...', res)
?? ??? ??? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ??? ??? ?});
?? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?});
?? ??? ??? ??? ??? ?recorderManager.start(option); // 開始錄音時(shí),建立ws連接
?? ??? ??? ??? ??? ?this.bulidSocketConnect();
?? ??? ??? ??? ??? ?//setTimeout(this.bulidSocketConnect, 2000) // ?main延遲2秒入口建立ws連接
?? ??? ??? ??? ?}
?? ??? ??? ??? ?if (e.content.text === "停止評(píng)測(cè)錄音") {
?? ??? ??? ??? ??? ?this.speakMark = '開始評(píng)測(cè)錄音'
?? ??? ??? ??? ??? ?// 3、發(fā)送最后一幀..........................................
?? ??? ??? ??? ??? ?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('最后一幀發(fā)送成功...', res)
?? ??? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ??? ?fail(res) {
?? ??? ??? ??? ??? ??? ??? ?console.log('最后一幀發(fā)送失敗...', res)
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?});
?? ??? ??? ??? ??? ?console.log("發(fā)送最后一幀", params)
?? ??? ??? ??? ??? ?console.log('錄音結(jié)束');
?? ??? ??? ??? ??? ?recorderManager.stop();
?? ??? ??? ??? ?}
?? ??? ??? ?},文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-544344.html
5、直接可運(yùn)行的DMEO可以文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-544344.html
到了這里,關(guān)于UNIAPP調(diào)用訊飛語(yǔ)音評(píng)測(cè)API的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!