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

总结

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

相关推荐
Hello__777712 小时前
开源鸿蒙 Flutter 实战|自定义开关组件全流程实现
flutter·开源·harmonyos
candyTong17 小时前
一觉醒来,大模型就帮我排查完页面性能问题
前端·javascript·架构
魔术师Grace17 小时前
我给 AI 做了场入职培训
前端·程序员
玩嵌入式的菜鸡18 小时前
网页访问单片机设备---基于mqtt
前端·javascript·css
前端一小卒18 小时前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
滑雪的企鹅.19 小时前
HTML头部元信息避坑指南大纲
前端·html
一拳不是超人19 小时前
老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌
前端·ai编程
excel21 小时前
如何解决 Nuxt DevTools 中关于 unstorage 包的报错
前端
Rust研习社21 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
C澒1 天前
AI 生码 - API2Code:接口智能匹配与 API 自动化生码全链路设计
前端·低代码·ai编程