鸿蒙Next - 原生API实现实时语音识别

鸿蒙原生提供的许多方法方便了应用的各种复杂业务实现,这期来分享一下原生的语音识别实现思路和流程。

官方文档

实现思路

具体的的实现主要分为两个部分:语音识别引擎和音频捕获。

在代码实现时,顺序不重要,关键在于分别启动语音识别器和音频捕获器后通过后者的回调函数使前者工作。


1. 语音识别引擎的初始化

在实现实时语音识别功能时,首先需要创建并配置语音识别引擎。以下是关键步骤:

步骤1:创建引擎

TypeScript 复制代码
let extraParam = { "locate": "CN", "recognizerMode": "short" };
let initParamsInfo = {
  language: 'zh-CN',
  online: 1,
  extraParams: extraParam
};
this.asrEngine = await speechRecognizer.createEngine(initParamsInfo);

先调用createEngine方法来初始化语音识别引擎。设置语言为中文,并指定识别模式。

步骤2:设置回调监听器

TypeScript 复制代码
// 创建回调对象
let setListener: speechRecognizer.RecognitionListener = {
  // 开始识别成功回调
  onStart(sessionId: string, eventMessage: string) {
    Logger.info(`onStart, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
  },
  // 事件回调
  onEvent(sessionId: string, eventCode: number, eventMessage: string) {
    Logger.info(`onEvent, sessionId: ${sessionId} eventCode: ${eventCode} eventMessage: ${eventMessage}`);
  },
  // 识别结果回调,包括中间结果和最终结果
  onResult: (sessionId: string, result: speechRecognizer.SpeechRecognitionResult) => {
    Logger.info(`onResult, sessionId: ${sessionId} sessionId: ${JSON.stringify(result)}`);
    this.onChange(result.result)    //结合具体业务修改即可
    this.keyword = result.result  //结合具体业务修改即可
  },
  // 识别完成回调
  onComplete: (sessionId: string, eventMessage: string) => {
    this.voiceState = VoiceState.DEFAULT
    Logger.info(`onComplete, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
    this.onComplete(this.keyword)    //结合具体业务修改即可
    this.keyword = ''    //结合具体业务修改即可
  },
  // 错误回调
  onError(sessionId: string, errorCode: number, errorMessage: string) {
    Logger.error(`onError, sessionId: ${sessionId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
  }
}
this.asrEngine.setListener(setListener);

我们创建了一个setListener对象来接收语音识别的回调信息,包括识别开始、结果返回和错误处理。每当识别结果更新时,我们将其存储到this.keyword中,以便页面展示使用。

步骤3:开始语音识别

TypeScript 复制代码
let audioParam = {
  audioType: 'pcm',
  sampleRate: 16000,
  soundChannel: 1,
  sampleBit: 16
};
let extraParams: Record<string, Object> = { "vadBegin": 2000, "vadEnd": 3000, "maxAudioDuration": 40000 };
let recognizerParams: speechRecognizer.StartParams = {
  sessionId: this.sessionId,
  audioInfo: audioParam,
  extraParams: extraParams
};
this.asrEngine.startListening(recognizerParams);

在调用startListening方法时,设置音频信息参数,包括采样率和声道。注意这里的参数需要与后面捕获的音频格式一致


2. 音频输入的捕获

捕获音频的具体步骤如下:

步骤1:创建音频捕获器

TypeScript 复制代码
let audioCapturerOptions = {
  streamInfo: {
    samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000,
    channels: audio.AudioChannel.CHANNEL_1,
    sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
    encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
  },
  capturerInfo: {
    source: audio.SourceType.SOURCE_TYPE_MIC,
    capturerFlags: 0
  }
};
this.audioCapturer = await audio.createAudioCapturer(audioCapturerOptions);

配置音频捕获器的参数,确保与语音识别引擎接收格式一致。这里指定了采样率、声道及编码格式,以确保音频数据的质量。

步骤2:处理音频数据

TypeScript 复制代码
let readDataCallback = (buffer) => {
  let uint8Array = new Uint8Array(buffer);
  this.asrEngine?.writeAudio(this.sessionId, uint8Array);
};
this.audioCapturer.on('readData', readDataCallback);

为音频捕获器设置了数据读取的回调函数。当捕获到音频数据时,它将被转换为Uint8Array格式并发送到语音识别引擎进行处理。这一步确保了音频数据能够实时传递给识别引擎,从而实现语音识别结果实时的根据输入变化。

步骤3:开始录音

TypeScript 复制代码
await this.audioCapturer.start();
this.voiceState = VoiceState.VOICING;  //根据业务变化,用于判断当前识别的状态

在成功设置音频捕获器和回调后,调用start()方法开始录音并更新语音状态,准备进行语音识别。


关闭语音识别
TypeScript 复制代码
// 结束语音识别
async closeRecord() {
  this.audioCapturer?.stop() // 停止录制
  this.audioCapturer?.release() // 释放资源
  this.asrEngine?.finish(this.sessionId) // 结束识别
  this.asrEngine?.shutdown() // 释放引擎资源
  this.voiceState = VoiceState.VOICEOVER  //根据业务变化,用于判断当前识别的状态
}

总结

没有总结,用于简单的应用场景很合适。

相关推荐
Fenderisfine5 分钟前
shadcn-vue 快速入门(2)
前端·javascript·vue.js
It'sMyGo19 分钟前
Javascript数组研究03_手写实现_fill_filter_find_findIndex_findLast_findLastIndex
前端·javascript·typescript
iQM7522 分钟前
X-Spreadsheet使用教程:打造你的Web端电子表格应用
前端·javascript·arcgis
凌云行者26 分钟前
使用rust写一个Web服务器——多线程版本
服务器·前端·rust
FanZheGOGOGO29 分钟前
cscode搭建vue项目
前端·javascript·vue.js
大今野44 分钟前
python三局两胜游戏
前端·python·游戏
国王不在家1 小时前
ts类型体操-简单篇
前端·javascript
光影少年1 小时前
HTML 与 ES6 是前端开发的两大核心技术
前端·html·es6
陈序缘1 小时前
Go语言实现长连接并发框架 - 任务执行流上下文
java·linux·服务器·开发语言·前端·后端·golang
泉城清晨的晚风2 小时前
react+antdMobie实现消息通知页面样式
前端·react.js