vue2对接科大讯飞-语音听写

需要https的才可以使用功能,不然报错‘不支持录音’
科大讯飞文档
下载的demo内js存放目录

在这里插入图片描述在这里插入图片描述

1,CryptoJS我是安装的依赖形式

在这里插入图片描述

<template>
  <div style="width: 100%;height: 100%;">
    <div class="speechBut pr" :class="disDown ? 'ac' : ''" @click="startRecording">
      <div
        style="position: absolute;bottom: 5px;left: 50%;transform: translateX(-50%);text-align: center;">
        <p style="margin: 0;">{{ btnText }}</p>
        <!-- <div>{{ resultText }}</div> -->
      </div>
    </div>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js';

// import '../../../../public/xfyun/utilJS/crypto-js.js'; //鉴权的引用地址
// import '../../../../public/xfyun/utilJS/index.umd.js'; // 调用Web Speech API 的依赖,应该是官方的写的工具类
const RecorderManager = require('../../../../public/xfyun/dist/index.umd.js');

export default {
  name: '',
  components: {},
  props: {
  },
  data() {
    return {
      disDown: false,
      btnText: "开始录音",
      btnStatus: "UNDEFINED", // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"
      recorder: new RecorderManager('../xfyun/dist'),// 这个指向不存在的文件夹也没事
      APPID: "", // TODO 你的讯飞模型APPID
      API_SECRET: "", // TODO 你的讯飞模型API_SECRET
      API_KEY: "", // TODO 你的讯飞模型API_KEY
      iatWS: null, //监听录音的变量
      resultText: '', // 识别结果
      resultTextTemp: '',
      countdownInterval: null
    };
  },
  computed: {
  },
  mounted() {
    // 定义监听开始的函数
    console.log('recorder:', this.recorder); // 打印 recorder 确认是否初始化成功
    this.recorder.onStart = () => {
      this.changeStatus("OPEN");
    };
    this.recorder.onFrameRecorded = this.onFrameRecorded;
    this.recorder.onStop = this.onStop;
  },
  methods: {
    // 按钮点击的启动 | 结束函数
    startRecording() {
      // console.log('当前状态',this.btnStatus)
      if (this.btnStatus === "UNDEFINED" || this.btnStatus === "CLOSED") {
        this.disDown = true;
        this.connectWebSocket();
      } else if (this.btnStatus === "CONNECTING" || this.btnStatus === "OPEN") {
        // 结束录音
        this.disDown = false;
        this.recorder.stop();
      }
    },
    // 生成 WebSocket URL 生成规则由平台决定
    getWebSocketUrl() {
      // 请求地址根据语种不同变化
      var url = "wss://iat-api.xfyun.cn/v2/iat";
      var host = "iat-api.xfyun.cn";
      var apiKey = this.API_KEY;
      var apiSecret = this.API_SECRET;
      var date = new Date().toGMTString();
      var algorithm = "hmac-sha256";
      var headers = "host date request-line";
      var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`;
      var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
      var signature = CryptoJS.enc.Base64.stringify(signatureSha);
      var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
      var authorization = btoa(authorizationOrigin);
      url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
      return url;
    },
    // 加密工具函数
    toBase64(buffer) {
      var binary = "";
      var bytes = new Uint8Array(buffer);
      var len = bytes.byteLength;
      for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
      }
      return window.btoa(binary);
    },
    // 计数函数
    countdownFun() {
      let seconds = 60;
      this.btnText = `录音中(${seconds}s)`;
      this.countdownInterval = setInterval(() => {
        seconds = seconds - 1;
        if (seconds <= 0) {
          clearInterval(this.countdownInterval);
          this.recorder.stop();
        } else {
          this.btnText = `录音中(${seconds}s)`;
        }
      }, 1000);
    },
    // 录音状态变化函数
    changeStatus(status) {
      this.btnStatus = status;
      if (status === "CONNECTING") {
        this.btnText = "建立连接中";
        this.resultText = '';
        this.resultTextTemp = "";
      } else if (status === "OPEN") {
        this.countdownFun();
      } else if (status === "CLOSING") {
        this.btnText = "关闭连接中";
      } else if (status === "CLOSED") {
        this.btnText = "开始录音";
      }
    },
    // 结果解析函数
    renderResult(resultData) {
      let that = this
      // 识别结束
      let jsonData = JSON.parse(resultData);
      if (jsonData.data && jsonData.data.result) {
        let data = jsonData.data.result;
        let str = "";
        let ws = data.ws;
        for (let i = 0; i < ws.length; i++) {
          str = str + ws[i].cw[0].w;
        }
        // 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
        // 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
        if (data.pgs) {
          if (data.pgs === "apd") {
            // 将resultTextTemp同步给resultText
            that.resultText = that.resultTextTemp;
          }
          // 将结果存储在resultTextTemp中
          that.resultTextTemp = that.resultText + str;
        } else {
          that.resultText = that.resultText + str;
        }
        // that.$emit('toTxt',that.resultText)
      }
      if (jsonData.code === 0 && jsonData.data.status === 2) {
        this.iatWS.close();
      }
      if (jsonData.code !== 0) {
        this.iatWS.close();
        console.error(jsonData);
      }
    },
    // 连接 WebSocket
    connectWebSocket() {
      const websocketUrl = this.getWebSocketUrl();
      if ("WebSocket" in window) {
        this.iatWS = new WebSocket(websocketUrl);
      } else if ("MozWebSocket" in window) {
        this.iatWS = new MozWebSocket(websocketUrl);
      } else {
        alert("浏览器不支持WebSocket");
        return;
      }
      this.changeStatus("CONNECTING");
      this.iatWS.onopen = (e) => {
        // 开始录音
        this.recorder.start({
          sampleRate: 16000,
          frameSize: 1280,
        });
        var params = {
          common: {
            app_id: this.APPID,
          },
          business: {
            language: "zh_cn",
            domain: "iat",
            accent: "mandarin",
            vad_eos: 5000,
            dwa: "wpgs",
          },
          data: {
            status: 0,
            format: "audio/L16;rate=16000",
            encoding: "raw",
          },
        };
        this.iatWS.send(JSON.stringify(params));
      };
      this.iatWS.onmessage = (e) => {
        this.renderResult(e.data);
      };
      this.iatWS.onerror = (e) => {
        console.error(e);
        this.recorder.stop();
        this.changeStatus("CLOSED");
      };
      this.iatWS.onclose = (e) => {
        this.recorder.stop();
        this.changeStatus("CLOSED");
      };
    },
    // 处理回调的结果
    onFrameRecorded({ isLastFrame, frameBuffer }) {
      if (this.iatWS.readyState === this.iatWS.OPEN) {
        this.iatWS.send(
          JSON.stringify({
            data: {
              status: isLastFrame ? 2 : 1,
              format: "audio/L16;rate=16000",
              encoding: "raw",
              audio: this.toBase64(frameBuffer),
            },
          })
        );
        if (isLastFrame) {
          this.changeStatus("CLOSING");
        }
      }
    },
    // 停止录音的处理
    onStop() {
      clearInterval(this.countdownInterval);
    },
  }
};
</script>

<style scoped>
.speechBut {
  cursor: pointer;
  width: 100%;
  height: 100%;
}

.speechBut.ac {}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值