ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

【第 08 课 | Core Speech Kit实战:端侧语音识别与合成的完整实现】

【第 08 课 | Core Speech Kit实战:端侧语音识别与合成的完整实现】

适用AI工具:DevEco Code / Cursor
前置博客:第02篇
预计阅读时间:20分钟

一、端侧语音:为什么值得鸿蒙开发者认真做

Core Speech Kit 提供端侧语音识别(ASR)与语音合成(TTS)能力,两大卖点:离线可用与数据不出设备。对会议记录、驾驶场景、无障碍等应用,这不仅是功能,更是合规刚需。

端侧方案与云端的取舍很简单:短指令、隐私敏感、弱网环境用端侧;超长音频转写、多语种混说可走云端补充。本篇聚焦端侧完整实现。

二、能力全景与调用链路

语音转文字

文字转语音

否

是

申请麦克风权限

业务需求

ASR: createEngine 创建识别引擎

TTS: createEngine 创建合成引擎

startListening 开始录音

onResult 流式返回分段结果

用户停止?

finish 结束并释放引擎

speak 传入文本与发音人参数

onData 回调音频流/直接播报

stop/shutdown 释放

统一由 AudioRenderer 管理焦点

三、ASR:语音转文字完整实现

3.1 权限与引擎创建

先在module.json5声明麦克风权限,并做运行时动态申请:

"requestPermissions":[{"name":"ohos.permission.MICROPHONE","reason":"$string:mic_reason","usedScene":{"abilities":["EntryAbility"],"when":"inuse"}}]

创建识别引擎并启动监听:

import{speechRecognizer}from'@kit.CoreSpeechKit';letengine:speechRecognizer.SpeechRecognitionEngine;asyncfunctionstartAsr(context:Context):Promise<void>{constextraParam:Record<string,Object>={'locate':'CN','recognizerMode':'short'// 短句模式,实时性最好};constinitInfo:speechRecognizer.CreateEngineParams={language:'zh-CN',online:1,// 端侧引擎extraParams:extraParam};engine=awaitspeechRecognizer.createEngine(initInfo);engine.on('result',(event:speechRecognizer.SpeechRecognitionResult)=>{// isLast 为 false 时是中间结果,可做"边说边显示"this.recognizedText=event.result;});engine.on('error',(err)=>{// 常见错误码:9400002 无录音权限 / 9400003 引擎忙this.handleAsrError(err);});engine.startListening({sessionId:this.sessionId,audioInfo:null,extraParams:null});}

3.2 AI 用法:错误分支与状态机生成

ASR 的业务难点不在主流程,而在错误分支与 UI 状态机(录音中/识别中/无权限/引擎忙的互斥切换)。这是 AI 最擅长的机械活:

为 ASR 功能生成完整状态机:Idle→Requesting→Listening→Recognizing→Error。
错误码 9400002 引导用户去设置开权限,9400003 延迟重试并设置最大3次。
生成 ArkTS 状态管理代码与对应 UI 提示。

AI 生成的状态机 + 权限引导 UI 直接可用,人工只需补业务文案。实测这类"状态机 + 错误引导"交给 AI,比手写节省一半时间,且分支覆盖更全(人容易漏"连续两次引擎忙"这种边角)。

3.3 离线识别与多方言

端侧引擎支持离线识别,弱网/无网自动走本地模型,代码无需区分——online: 1的引擎创建后由系统智能调度。方言方面,主流方言(粤语、四川话等)已进入识别语言列表,AI 可帮你查 Kit 文档生成当前支持的方言清单与对应 locale 参数表,避免硬编码踩空。

四、TTS:语音合成与播报

import{textToSpeech}from'@kit.CoreSpeechKit';asyncfunctionspeak(context:Context,text:string):Promise<void>{constengine=awaittextToSpeech.createEngine({language:'zh-CN',online:1,extraParams:{style:'interaction-broadcast',locate:'CN',name:'EngineName'}});constparams:textToSpeech.SpeakParams={requestId:this.reqId,extraParams:{speed:1.0,volume:1.0,pitch:1.0,soundChannel:textToSpeech.SpeechAudioChannel.AUDIO_MUSIC// 走媒体通道,可后台播}};engine.speak(text,params);}

注意soundChannel的选择:导航提示类走默认音频通道即可;长内容朗读(听文章)用AUDIO_MUSIC媒体通道,配合后台任务保活,锁屏不中断。

五、组合实战:会议速记

ASR + TTS 组合的经典场景是会议速记:实时转写上屏 + 关键节点语音确认。架构要点:

  • ASR 中间结果高频刷新 UI 时,节流到 300ms 更新一次,避免渲染抖动
  • 转写文本分段落缓存到 preferences,异常退出可恢复
  • 结束后把文本交给 AI 做摘要——这也是 2026 年很成熟的玩法:端侧 Kit 拿原始数据,云端 LLM 做增值处理

给 AI 的组合指令示例:

实现会议速记页:ASR 实时转写(300ms 节流上屏)、暂停/继续、
结束后生成摘要(调用云端接口)。生成页面代码与数据持久化层。

六、避坑清单

  • 引擎是重资源:createEngine 耗时且占内存,全局复用一个实例,页面销毁只 stop 不 shutdown。
  • 中间结果别直接存库:等isLast: true的最终结果再持久化,否则同一句话会存多遍。
  • 权限被拒后的引导:9400002 错误要给出"去设置"入口,纯 toast 用户会以为是功能坏了。
  • 录音指示器:系统会在状态栏展示录音图标,应用内再加一个明确的录音状态 UI,避免用户困惑。

七、下一步

语音之后是视觉。下一篇 Core Vision Kit:人脸检测、文字识别与图像超分的实战集成。


RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进