【UNI-APP】阿里NLS一句话听写typescript模块

阿里提供的demo代码都是javascript,自己捏个轮子。参考着自己写了一个阿里巴巴一句话听写Nls的typescript模块。VUE3的组合式API形式

startClient:开始听写,注意下一步要尽快开启识别和传数据,否则6秒后会关闭

startRecognition:开始识别事务,传入识别回调,可以打印字符或显示到屏幕

sendSound:发送二进制PCM数据(格式16MHz16bit)

stopRecognition:结束识别事务

/**
 * 阿里语音,一句话识别模块for ccframe
 *
 * 无心跳设计,非长连接推送,因此在需要使用的时候才进行连接
 *
 * @Jim 2024/07/08
 */
import * as utils from '@/utils/index'
import { nextTick } from 'vue'
// import Global from '@/utils/constants'

const NLS_SERVER_URL = 'wss://nls-gateway.aliyuncs.com/ws/v1'
const NLS_MODE = 'SpeechRecognizer' // 一句话识别
const WEBSOCKET_MAX_RETRY = 3
const RECONNECT_INTERVAL = 3000

interface INlsConfig {
  url?: string
  appkey: string // 应用的key
  token: string // 从服务器获得,要缓存
}

let client: (UniNamespace.SocketTask & { readyState?: WsState }) | undefined
const clientId = utils.uuid(utils.UUIDFormat.StandardCompact)
let taskId: string = ''
let config: INlsConfig
let reconnectAttempts = 0
let taskStarted = false

enum WsState {
  CONNECTING,
  OPEN,
  CLOSING,
  CLOSED
}

/**
 *
 * @param action
 * @returns 请求json
 */
const buildMsg: (action: string, payload: Record<string, any>) => string = (
  action,
  payload = {}
) => {
  if (taskId.length === 0) {
    taskId = utils.uuid(utils.UUIDFormat.StandardCompact)
  }
  const msg = {
    header: {
      message_id: utils.uuid(utils.UUIDFormat.StandardCompact),
      task_id: taskId,
      namespace: NLS_MODE,
      name: action,
      appkey: config.appkey
    },
    payload,
    context: {
      sdk: {
        name: 'nls-wx-sdk',
        version: '0.0.1',
        language: 'wxjs'
      }
    }
  }
  return JSON.stringify(msg, null, 0)
}

/**
 * 开启连接,开启后立即要传,否则会被关闭.
 * @param config
 * @param callback
 */
export const startClient = (
  conf?: INlsConfig,
  startCallback?: () => void,
  recognizedCallback?: (text: string) => void
) => {
  if (client && client.readyState !== WsState.CLOSED) {
    // 关闭原连接
    client.close({})
  }

  client = uni.connectSocket({
    url: conf.url ?? NLS_SERVER_URL,
    tcpNoDelay: true,
    header: {
      'X-NLS-Token': conf?.token ?? config.token
    },
    success: (res) => {
      if (!config) config = conf
      console.log(`connected to ${NLS_SERVER_URL} success`)
    },
    fail: (res) => {
      console.log(`connect to ${NLS_SERVER_URL} failed:${res.errMsg}`)
    }
  })
  client.readyState = WsState.CONNECTING

  client.onMessage((res) => {
    if (typeof res.data === 'string') {
      const msgObj = JSON.parse(res.data)
      switch (msgObj?.header?.name) {
        case 'RecognitionStarted': {
          console.log('started')
          break
        }
        case 'RecognitionResultChanged': {
          if (recognizedCallback) {
            const text = msgObj?.payload?.result
            if (text) {
              recognizedCallback(text)
            }
          }
          console.log('changed')
          break
        }
        case 'RecognitionCompleted': {
          const text = msgObj?.payload?.result
          if (text) {
            recognizedCallback(text)
          }
          taskStarted = false // 结束识别
          break
        }
        case 'TaskFailed': {
          taskStarted = false // 结束识别
          break
        }
      }
    }
    console.log('recv:' + res.data)
  })

  client.onOpen(() => {
    reconnectAttempts = 0
    client.readyState = WsState.OPEN
    if (startCallback) nextTick(startCallback)
  })

  client.onError((error) => {
    console.error('WebSocket error:', error)
    if (reconnectAttempts < WEBSOCKET_MAX_RETRY) {
      setTimeout(() => startClient(), RECONNECT_INTERVAL)
    } else {
      console.error('Max reconnect attempts reached')
    }
  })

  client.onClose(() => {
    client.readyState = WsState.CLOSED
    console.log('connection closed')
  })
}

export const startRecognition = () => {
  if (client && client.readyState === WsState.OPEN)
    client.send({
      data: buildMsg('StartRecognition', {
        format: 'opus',
        sample_rate: 16000,
        enable_intermediate_result: true,
        enable_punctuation_prediction: true,
        enable_inverse_text_normalization: true
      }),
      success: (res) => {
        taskStarted = true
      }
    })
}

export const stopRecognition = () => {
  if (client && client.readyState === WsState.OPEN)
    client.send({
      data: buildMsg('StopRecognition', {
        format: 'opus',
        sample_rate: 16000,
        enable_intermediate_result: true,
        enable_punctuation_prediction: true,
        enable_inverse_text_normalization: true
      }),
      complete: () => {
        taskStarted = false // 不管是否成功,都不发送音频了
      }
    })
}

export const sendSound = (msgBytes: ArrayBuffer) => {
  if (client && client.readyState === WsState.OPEN && taskStarted)
    client.send({
      data: msgBytes,
      success: (res) => {
        console.log('send ' + msgBytes.byteLength + ' success')
      }
    })
}

util的uuid工具见我前一篇文章https://mp.csdn.net/mp_blog/creation/editor/140267684icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/140267684

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/791428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MapReduce底层原理详解:大案例解析(第32天)

系列文章目录 一、MapReduce概述 二、MapReduce工作机制 三、Map&#xff0c;Shuffle&#xff0c;reduce阶段详解 四、大案例解析 文章目录 系列文章目录前言一、MapReduce概述二、MapReduce工作机制1. 角色与组件2. 作业提交与执行流程1. 作业提交&#xff1a;2. Map阶段&…

六、数据可视化—Echars(爬虫及数据可视化)

六、数据可视化—Echars&#xff08;爬虫及数据可视化&#xff09; Echarts应用 Echarts Echarts官网&#xff0c;很多图表等都是我们可以 https://echarts.apache.org/zh/index.html 是百度自己做的图表&#xff0c;后来用的人越来越多&#xff0c;捐给了orange组织&#xf…

Django项目创建的准备工作【3】

【 一 】建立数据库 创建库: 命令&#xff08;指定编码&#xff09; 创建用户: 并授权 用户: luffy: 密码xxxxxx , 只授予luffy库权限 使用mysql创建lufy数据库 root账号和密码--->万一泄露---》整个数据库就不安全了。 创建个用户&#xff0c;这个用户只对当前项目 库 有…

不同材质酒店智能开关的功能特点详解

在当今的酒店行业中&#xff0c;智能开关已成为提升客户体验和管理效率的重要设备。而不同材质的智能开关&#xff0c;不仅在外观上各具特色&#xff0c;其功能特点也有所差异。 玻璃材质智能开关&#xff1a; 玻璃材质的智能开关给人一种时尚、简约且高端的感觉。其表面光滑&a…

前端面试39(关于git)

针对前端开发者的Git面试题可以覆盖Git的基础概念、常用命令、工作流程、团队协作、以及解决冲突等方面。以下是一些具体的Git面试 Git基础知识 什么是Git&#xff1f; Git是一个分布式版本控制系统&#xff0c;用于跟踪计算机文件的更改&#xff0c;并协调多个人共同在一个项…

tensorflow张量生成以及常用函数

张量tensor&#xff1a;多维数组&#xff08;列表&#xff09; 阶&#xff1a;张量的维数 维数 阶 名字 例子 0-D 0 标量 scalar s 1&#xff0c; 2&#xff0c; 3 1-D 1 向量 vector…

JS进阶-原型

学习目标&#xff1a; 掌握原型 学习内容&#xff1a; 原型constructor属性对象原型原型继承原型链综合案例 原型&#xff1a; 构造函数通过原型分配的函数是所有对象所共享的。 JavaScript规定&#xff0c;每一个构造函数都有一个prototype属性&#xff0c;指向另一个对象&…

vscode c++可以找到声明却无法自动补全

这个问题折磨了我将近一个月&#xff0c;今天终于被解决了&#xff0c;特此记录 情景再现 事情的起因是我在学习华为的Ascend C算子&#xff0c;需要编写C代码。关于怎么下载库文件怎么编译之类的不是本文的重点&#xff0c;重点是自动补全。 我已经拿到库文件了&#xff0c…

力扣题解(设计跳表)

1206.设计跳表 已解答 不使用任何库函数&#xff0c;设计一个 跳表 。 跳表 是在 O(log(n)) 时间内完成增加、删除、搜索操作的数据结构。跳表相比于树堆与红黑树&#xff0c;其功能与性能相当&#xff0c;并且跳表的代码长度相较下更短&#xff0c;其设计思想与链表相似。 …

Linux文件编程应用

目录 一、实现cp命令 二、修改程序的配置文件 三、写一个整数/结构体到文件 1.写一个整数到文件 2.写一个结构体到文件 四、写结构体数组到文件 我们学习了文件编程的常用指令以及了解文件编程的基本步骤后&#xff0c;试着来写一些程序实现某些功能。&#xff08;没有学…

oracle哪些后台进程不能杀?

oracle 有很多的后台进程&#xff0c;在遇到特殊情况的时候如锁表&#xff0c;如果等待的是一个后台进程&#xff0c;那这时就需要考量是不是能杀掉这个后台进程&#xff1f;杀掉这个后台进程会不会引起实例崩溃&#xff1f;本着实践出真知&#xff0c;本文针对oracle 11g&…

昇思25天学习打卡营第23天 | Pix2Pix实现图像转换

内容介绍&#xff1a; Pix2Pix是基于条件生成对抗网络&#xff08;cGAN, Condition Generative Adversarial Networks &#xff09;实现的一种深度学习图像转换模型&#xff0c;该模型是由Phillip Isola等作者在2017年CVPR上提出的&#xff0c;可以实现语义/标签到真实图片、灰…

二分法求函数的零点 信友队

题目ID&#xff1a;15713 必做题 100分 时间限制: 1000ms 空间限制: 65536kB 题目描述 有函数&#xff1a;f(x) 已知f(1.5) > 0&#xff0c;f(2.4) < 0 且方程 f(x) 0 在区间 [1.5,2.4] 有且只有一个根&#xff0c;请用二分法求出该根。 输入格式 &#xff08;无…

政安晨:【Keras机器学习示例演绎】(五十三)—— 使用 TensorFlow 决策森林进行分类

目录 简介 设置 准备数据 定义数据集元数据 配置超参数 实施培训和评估程序 实验 1&#xff1a;使用原始特征的决策森林 检查模型 实验 2&#xff1a;目标编码决策森林 创建模型输入 使用目标编码实现特征编码 使用预处理器创建梯度提升树模型 训练和评估模型 实验…

从零开始学习嵌入式----C语言框架梳理与后期规划

目录 一、环境搭建. 二、见解 三、C语言框架梳理 四、嵌入式学习规划流程图&#xff08;学习顺序可能有变&#xff09; 一、环境搭建. C语言是一门编程语言&#xff0c;在学习的时候要准备好环境。我个人比较喜欢用VS,具体怎么安装请百度。学习C语言的时候&#xff0c;切忌…

Spring中如何操作Redis

Spring毕竟是Java中的一个主流框架&#xff0c;如何在这个框架中使用Redis呢&#xff1f; 创建项目并引入相关依赖 然后进行创建。 至此就将Redis的相关依赖引入进来了。 编写Redis配置 将application.properties修改成application.yml 然后编写如下配置&#xff1a; spr…

各向异性含水层中地下水三维流基本微分方程的推导

各向异性含水层中地下水三维流基本微分方程的推导 参考文献&#xff1a; [1] 刘欣怡,付小莉.论连续性方程的推导及几种形式转换的方法[J].力学与实践,2023,45(02):469-474. 文章链接 水均衡的基本思想&#xff1a; ∑ 流 入 − ∑ 流 出 Δ V \sum 流入-\sum 流出\Delta V ∑…

ArduPilot开源飞控之AP_Mount_Siyi

ArduPilot开源飞控之AP_Mount_Siyi 1. 源由2. 框架设计2.1 类和继承2.2 公共方法2.3 保护方法2.4 私有成员和方法2.5 解析状态2.6 重要成员变量 3. 重要方法3.1 AP_Mount_Siyi::init3.2 AP_Mount_Siyi::update3.3 AP_Mount_Siyi::read_incoming_packets3.4 AP_Mount_Siyi::proc…

LabVIEW实现LED显示屏视觉检测

为了满足LED显示屏在生产过程中的严格质量检测需求&#xff0c;引入自动化检测系统是十分必要的。传统人工检测方式存在检测强度高、效率低、准确性差等问题&#xff0c;自动化检测系统则能显著提高检测效率和准确性。视觉检测系统的构建主要包含硬件和软件两个部分。 视觉系统…

深度学习论文: LLaMA: Open and Efficient Foundation Language Models

深度学习论文: LLaMA: Open and Efficient Foundation Language Models LLaMA: Open and Efficient Foundation Language Models PDF:https://arxiv.org/pdf/2302.13971.pdf PyTorch: https://github.com/shanglianlm0525/PyTorch-Networks 1 概述 本文介绍了LLaMA&#xff0…