当前位置: 首页 > news >正文

HarmonyOS 原生智能之语音识别实战

HarmonyOS 原生智能之语音识别实战

背景

公司很多业务场景使用到了语音识别功能,当时我们的语音团队自研了语音识别模型,方案是云端模型加端侧SDK交互,端侧负责做语音采集、VAD、opus编码,实时传输给云端,云端识别后返回识别结果。这些业务场景在适配鸿蒙的过程发现HarmonyOS 原生智能中提供了本地语音识别SDK,动手封装一波。

场景介绍

原生语音识别能力支持两种模式:

  • 短语音模式(不超过60s)
  • 长语音模式(不超过8h)

API接口介绍

1. 引擎初始化

speechRecognizer.createEngine

let asrEngine: speechRecognizer.SpeechRecognitionEngine;
// 创建引擎,通过callback形式返回
// 设置创建引擎参数
let extraParam: Record<string, Object> = {"locate": "CN", "recognizerMode": "short"};
let initParamsInfo: speechRecognizer.CreateEngineParams = {language: 'zh-CN',online: 1,extraParams: extraParam
};
// 调用createEngine方法
speechRecognizer.createEngine(initParamsInfo, (err: BusinessError, speechRecognitionEngine: speechRecognizer.SpeechRecognitionEngine) => {if (!err) {console.info('Succeeded in creating engine.');// 接收创建引擎的实例asrEngine = speechRecognitionEngine;} else {// 无法创建引擎时返回错误码1002200008,原因:引擎正在销毁中console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);}
});

主要是需要构建引擎参数speechRecognizer.CreateEngineParams:

  • language:语言
  • online:模式,1为离线,目前只支持离线引擎
  • extraParams:区域信息等
    • locate:区域信息,可选,不设置时默认为“CN”,当前仅支持“CN”
    • recognizerMode:识别模式,包含短语音short与场语音long
      回调中可以查看错误信息:
  1. 无法创建引擎时返回错误码1002200001,原因:语种不支持、模式不支持、初始化超时、资源不存在等导致创建引擎失败
  2. 无法创建引擎时返回错误码1002200006,原因:引擎正在忙碌中,一般多个应用同时调用语音识别引擎时触发
  3. 无法创建引擎时返回错误码1002200008,原因:引擎正在销毁中

2、设置RecognitionListener回调

回调主要处理识别过程中的事件,最主要的就是onResult处理识别内容,不同的对话对应不同的sessionId:

// 创建回调对象
let setListener: speechRecognizer.RecognitionListener = {// 开始识别成功回调onStart(sessionId: string, eventMessage: string) {},// 事件回调onEvent(sessionId: string, eventCode: number, eventMessage: string) {},// 识别结果回调,包括中间结果和最终结果onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {},// 识别完成回调onComplete(sessionId: string, eventMessage: string) {},// 错误回调,错误码通过本方法返回,如:返回错误码1002200006,识别引擎正忙,引擎正在识别中onError(sessionId: string, errorCode: number, errorMessage: string) {}
}
// 设置回调
asrEngine.setListener(setListener);

3、开始识别

let audioParam: speechRecognizer.AudioInfo = {audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16};
let extraParam: Record<string, Object> = {"vadBegin": 2000, "vadEnd": 3000, "maxAudioDuration": 40000};
let recognizerParams: speechRecognizer.StartParams = {sessionId: sessionId,audioInfo: audioParam,extraParams: extraParam
};
// 调用开始识别方法
asrEngine.startListening(recognizerParams);

主要是设置开始识别的相关参数:

  • sessionId:会话id,与onResult回调中的sessionId要对应
  • audioInfo:音频配置信息,可选
    • audioType:目前只支持PCM,如果要识别MP3文件等需要解码后再传给引擎
    • sampleRate:音频的采样率,当前仅支持16000采样率
    • sampleBit:音频返回的采样位数,当前仅支持16位
    • soundChannel:音频返回的通道数信息,当前仅支持通道1
    • extraParams:音频的压缩率,pcm格式音频默认为0
  • extraParams:额外配置信息,主要包含:
    • recognitionMode:实时语音识别模式(不传时默认为1)
      • 0:实时录音识别(需应用开启录音权限:ohos.permission.MICROPHONE),若需结束录音,则调用finish方法
      • 1:实时音频转文字识别,开启此模式时需要额外调用writeAudio方法,传入待识别音频流;
    • vadBegin:Voice Activity Detection(VAD)前端点设置,参数范围是[500,10000],不传参时默认为10000ms
    • vadEnd:Voice Activity Detection(VAD)后端点设置。参数范围是[500,10000],不传参时默认为800ms。
    • maxAudioDuration:最大支持音频时长
      • 短语音模式支持范围[20000-60000]ms,不传参时默认20000ms。
      • 长语音模式支持范围[20000 - 8 * 60 * 60 * 1000]ms。
        VAD作用主要是语音活动检测,对静音数据不进行识别

4、传入音频流

asrEngine.writeAudio(sessionId, uint8Array);

向引擎写入音频数据,可以从麦克风或者音频文件中读取音频流。
注意:音频流长度仅支持640或1280。

5、其他接口

  1. listLanguages:查询语音识别服务支持的语种信息
  2. finish:结束识别
  3. 取消识别:cancel
  4. shutdown:释放识别引起资源

最佳实践

实时识别的场景需要从麦克风实时读取音频,写入到asrEngine,在onResult回调中获取识别结果。
配置音频采集参数并创建AudioCapturer实例:

 import { audio } from '@kit.AudioKit';let audioStreamInfo: audio.AudioStreamInfo = {samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000, // 采样率channels: audio.AudioChannel.CHANNEL_1, // 通道sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式};let audioCapturerInfo: audio.AudioCapturerInfo = {source: audio.SourceType.SOURCE_TYPE_MIC,capturerFlags: 0};let audioCapturerOptions: audio.AudioCapturerOptions = {streamInfo: audioStreamInfo,capturerInfo: audioCapturerInfo};audio.createAudioCapturer(audioCapturerOptions, (err, data) => {if (err) {console.error(`Invoke createAudioCapturer failed, code is ${err.code}, message is ${err.message}`);} else {console.info('Invoke createAudioCapturer succeeded.');let audioCapturer = data;}});

这里注意采样率和声道以及采样位数要符合ASR引擎要求:16k采样、单声道、16位采样位数。
接着调用on(‘readData’)方法,订阅监听音频数据读入回调:

 import { BusinessError } from '@kit.BasicServicesKit';import { fileIo } from '@kit.CoreFileKit';let bufferSize: number = 0;class Options {offset?: number;length?: number;}let readDataCallback = (buffer: ArrayBuffer) => {//将buffer写入asr引擎asrEngine.writeAudio(sessionId, new Uint8Array(buffer));}audioCapturer.on('readData', readDataCallback);

这里注意写入buffer的大小显示,ASR只支持640或1280。

总结

本文介绍了 HarmonyOS 官方提供的语音识别能力,详解介绍了ASR引擎接口,最后基于麦克风采集数据实现了实时麦克风语音识别功能。

相关文章:

HarmonyOS 原生智能之语音识别实战

HarmonyOS 原生智能之语音识别实战 背景 公司很多业务场景使用到了语音识别功能&#xff0c;当时我们的语音团队自研了语音识别模型&#xff0c;方案是云端模型加端侧SDK交互&#xff0c;端侧负责做语音采集、VAD、opus编码&#xff0c;实时传输给云端&#xff0c;云端识别后…...

基于Gromacs的蛋白质与小分子配体相互作用模拟教程

在生命科学的广阔领域中&#xff0c;蛋白质与小分子配体之间的相互作用扮演着至关重要的角色。这些相互作用不仅影响着生物体内的各种生命活动&#xff0c;如信号传导、代谢调控和药物作用等&#xff0c;同时也是药物设计和开发的核心内容。因此&#xff0c;深入理解并模拟这些…...

Ubuntu下python3.12安装, 分布式 LLM 推理 exo 安装调试过程, 运行自己的 AI 集群

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” —调试有点废,文章有点长,希望大家用心看完,肯定能学废,感谢. 1. Ubuntu下python3.12安装 1.1 导入 Python 的稳定版 PPA,不用编译 sudo add-apt-repository ppa:deadsnakes/ppa sudo…...

pytest-bdd 行为驱动自动化测试

引言 pytest-bdd 是一个专为Python设计的行为驱动开发&#xff08;BDD&#xff09;测试框架&#xff0c;它允许开发人员使用自然语言&#xff08;如Gherkin&#xff09;来编写测试用例&#xff0c;从而使测试用例更易于理解和维护。 安装 通过pip安装 pip install pytest-b…...

PostgreSQL11 | 触发器

本文章代码已在pgsql11.22版本上运行且通过&#xff0c;展示页由pgAdmin8.4版本提供 上一篇总结了原著的第十章有关pgsql的视图的用法&#xff0c;本篇将总结pgsql的触发器的用法。 触发器 使用触发器可以自动化完成一些在插入数据或修改数据时&#xff0c;某些需要同期同步的…...

cesium canvas广告牌

在有些业务中&#xff0c;对场景中的广告牌样式要求比较高&#xff0c;需要动态显示一些数据&#xff0c;这个时候&#xff0c;我们可以通过将复杂背景样式制作成图片&#xff0c;通过canvas绘制图片和动态数据&#xff0c;从而达到比较好的显示效果。 1 CanvasMarker 类封装 …...

使用Floyd算法求解两点间最短距离

Floyd算法 Floyd算法又称为Floyd-Warshell算法&#xff0c;其实Warshell算法是离散数学中求传递闭包的算法&#xff0c;两者的思想是一致的。Floyd算法是求解多源最短路时通常选用的算法&#xff0c;经过一次算法即可求出任意两点之间的最短距离&#xff0c;并且可以处理有负权…...

linux“how_paras.sh“ E212: 无法打开并写入文件

经过一番测试和查找&#xff0c; [6localhost bin]$ find / -name "hello.sh" 2>/dev/null /home/6/bin/hello.sh [6localhost bin]$ ls hello.sh ls: 无法访问hello.sh: 没有那个文件或目录&#xff0c;为什么在/bin文件下却不能打开&#xff0c; [6localhost …...

CSS mask-image 实现边缘淡出过渡效果

使用场景 在生产环境中&#xff0c;遇到一个需求&#xff0c;需要在一个深色风格的大屏页面中&#xff0c;嵌入 Google Maps。为了减少违和感&#xff0c;希望地图四边能够淡出过渡。 这里的“淡出过渡”&#xff0c;关键是淡出&#xff0c;而非降低透明度。 基于 Google Ma…...

电子元器件—电容和电感(一篇文章搞懂电路中的电容和电感)(笔记)(面试考试必备知识点)电容和电感作用、用途、使用、注意事项、特点等(面试必备)-笔记(详解)

作者&#xff1a;Whappy 座右铭&#xff1a;不曾拥有&#xff0c;何来失去&#xff01; 时间&#xff1a;2024年8月2日08:40:04 一、电容的作用 储能&#xff1a; 电容器通过充电储存电荷在电容板上&#xff0c;形成电场储存电能。当需要释放储存的电能时&#xff0c;电荷…...

2024HDU Contest 5 Problem 5

题目链接 从大到小枚举gcd的值 d d d&#xff0c;以及编号为 d d d的倍数的点&#xff0c; [ d , 2 d , 3 d , … ] [d,2d,3d,\dots] [d,2d,3d,…]。 然后对于任何一条边 ( x , y ) (x,y) (x,y)&#xff0c;如果 x x x的子树和 y y y的子树里都有编号为 d d d倍数的点&#xf…...

nGQL入门

引言 nGQL&#xff08;NebulaGraph Query Language&#xff09;是用于操作 NebulaGraph 的查询语言。它的语法类似于 Cypher&#xff0c;但有自己独特的特性。以下是一些 nGQL 的基本语法和操作示例&#xff0c;以帮助你入门。 基本概念 节点&#xff08;Vertex&#xff09;…...

[CP_AUTOSAR]_系统服务_DEM模块(二)功能规范介绍

目录 1、DEM 功能规范描述1.1、Startup behavior1.2、Monitor re-initialization 在前面 《[CP_AUTOSAR]_系统服务_DEM模块&#xff08;一&#xff09;》文中&#xff0c;简要介绍了 DEM 模块的功能、与其它模块之间的功能交互&#xff0c;本文将接着介绍 DEM 模块的功能规范。…...

Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget

文章目录 一、常见Linux发行版本二、Linux中yum、rpm、apt-get、wget的区别2.1 yum2.2 rpm2.3 apt-get2.4 wget2.5 总结 三、CentOS中yum的作用3.1 yum清空缓存列表3.2 yum显示信息3.3 yum搜索、查看3.4 yum安装3.5 yum删除、卸载程序3.6 yum包的升级、降级 四、Ubuntu中apt-ge…...

IPython的使用技巧2

关注我&#xff0c;持续分享逻辑思维&管理思维&面试题&#xff1b; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导&#xff1b; 推荐专栏《10天学会使用asp.net编程AI大模型》&#xff0c;目前已完成所有内容。一顿烧烤不到的费用&#xff0c;让人能紧跟时代的…...

win10打开程序闪退的解决方法,亲测好用

当我们在使用win10系统的时候&#xff0c;可能会遇到安装某些程序后无法正常使用&#xff0c;一打开就闪退&#xff0c;或者点击右下角图标就消失了&#xff0c;而其他程序却可以正常打开使用。下面小编就来和大家分享亲测好用的win10打开程序闪退的解决办法。 问题原因分析&a…...

木舟0基础学习Java的第二十一天(数据库,MySQL,SQLyog)

数据库 数据库&#xff1a;按照数据结构来组织 存储数据的厂库 数据管理系统(Database Management System,DBMS)&#xff1a;一套操作和管理数据库的软件 用于简历 使用 维护数据库 关系型数据库&#xff1a;采用关系模型作为数据组织方式 逻辑结构是一张二维表 由行和列组成…...

python-鼠标绘画线条程序

闲来无聊简单编写了一个绘图小程序。 主要思路 主要是基于Python中的内置模块turtle编写的&#xff0c;简单扩展了一下&#xff0c;通过绑定事件能够达到鼠标绘制、删除、存储已经绘制图案的线条这几个功能。 路径结构 -draw- define.py- main.py- myturtle.py使用 点住鼠…...

【Python实战】如何优雅地实现 PDF 去水印?

话接上篇&#xff0c;自动化处理 PDF 文档&#xff0c;完美实现 WPS 会员功能 小伙伴们更关心的是如何去除 PDF 中的水印~ 今天&#xff0c;就来分享一个超简单的 PDF 去水印方法~ 1. 原理介绍 在上一篇中&#xff0c;我们介绍了如何将 PDF 文档转换成图片&#xff0c;图片…...

Keysight(原Agilent) E4980AL 精密 LCR 表特性与技术指标

Keysight(原Agilent) E4980AL 精密 LCR 表为基础 LCR 表树立了行业标准&#xff0c;可在多个频率范围内提供更佳的精度、速度和通用性。E4980AL 结合了种类繁多的附件&#xff0c;适用于一般研发和生产环境中的各种元件和材料测量。也可通过频率升级而提升投资回报率。 Keysig…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...