鸿蒙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  //根据业务变化,用于判断当前识别的状态
}

总结

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

相关推荐
爱分享的码瑞哥7 分钟前
利用正则表达式高效处理复杂HTML结构
前端·正则表达式·html
阿语!11 分钟前
Vue生命周期详解
前端·vue.js
蓝桉柒711 分钟前
web前端开发--动画效果
开发语言·前端·css
叫我王员外就行19 分钟前
Vue第一篇:组件模板总结
前端·javascript·vue.js
GoldenFingers28 分钟前
【体验分享】各前端部署平台详细体验汇总
前端·部署
Dragon Wu1 小时前
前端框架 react 性能优化
前端·javascript·react.js·性能优化·前端框架·react
Gungnirss1 小时前
前后端分离,后端拦截器无法获得前端请求的token
java·前端·token
zhongcx011 小时前
鸿蒙NEXT开发案例:二维码的生成与识别
华为·harmonyos·鸿蒙·鸿蒙next
五秒法则2 小时前
从搭建uni-app+vue3工程开始
前端·vue.js·uni-app
风之舞_yjf2 小时前
css基础(27)_行内、行内块元素之间的空白问题
前端·css