鸿蒙app 语音控制集成(对接小艺/第三方TTS引擎) 【玩转华为云】
【摘要】 引言随着智能家居与移动终端的普及,语音控制已成为人机交互的重要方式。鸿蒙操作系统(HarmonyOS)提供分布式能力与系统级语音服务,支持对接系统语音助手(如小艺)及第三方 TTS/ASR 引擎,实现“动口不动手”的应用操控。本文档提供一套在鸿蒙 App 中集成语音控制的完整方案,涵盖与小艺对接、第三方 TTS 播报、语音识别与指令执行的闭环实现。技术背景鸿蒙语音能力:系统语音助手(小艺):...
引言
技术背景
-
鸿蒙语音能力: -
系统语音助手(小艺):通过 Want调用系统 Intent,由小艺完成语音识别与语义理解,再返回结果给应用。 -
分布式语音流转:跨设备接力语音任务(手机→智慧屏)。 -
第三方 ASR/TTS:可使用讯飞、百度、Azure 等云引擎或本地引擎(如 OpenSpeech)。
-
-
关键模块: -
@ohos.multimodalinput.inputDevice与@ohos.multimodalinput.voiceCommand(语音指令框架) -
@ohos.speech.tts:系统 TTS 接口 -
@ohos.app.ability.Want:用于拉起系统语音助手 -
网络请求库(axios/ohos.net.http)用于调用第三方云 ASR/TTS
-
-
权限: ohos.permission.MICROPHONE、ohos.permission.INTERNET(第三方云语音)
应用使用场景
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
原理解释
核心原理
-
语音识别(ASR): -
系统方案:通过 startAbility(Want)拉起小艺,小艺完成识别并返回结果。 -
第三方方案:采集麦克风 PCM 数据,上传云端或使用本地引擎识别。
-
-
语义理解与指令分发:解析识别文本,匹配预定义指令或调用 NLP 服务。 -
语音合成(TTS):将文本转为语音播放,可用系统 TTS 或第三方引擎。 -
闭环执行:根据指令操控 UI 或设备。
与小艺交互原理
Want设置 action: ohos.want.action.voiceAssistant,系统弹出小艺界面,识别完成后通过 onAbilityResult返回识别文本。核心特性
-
支持系统小艺与第三方 ASR/TTS 双通道 -
分布式语音任务流转 -
可配置离线/在线识别策略 -
支持自定义唤醒词(部分第三方引擎) -
与鸿蒙分布式设备虚拟化结合,实现跨端语音控制
原理流程图
graph TD
A[用户语音输入] --> B{选择识别方式}
B -->|系统小艺| C[构造Want调用小艺]
C --> D[小艺识别并返回文本]
B -->|第三方ASR| E[采集麦克风数据]
E --> F[上传云端/本地识别]
F --> D
D --> G[语义解析与指令匹配]
G --> H[执行应用内操作/设备控制]
H --> I{TTS播报结果?}
I -->|是| J[系统TTS或第三方TTS播报]
I -->|否| K[结束]
环境准备
-
DevEco Studio 4.0+ -
HarmonyOS SDK 9+ -
Language: ArkTS -
权限配置( module.json5):
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "语音识别需要麦克风",
"usedScene": { "abilities": ["MainAbility"], "when": "inuse" }
},
{
"name": "ohos.permission.INTERNET",
"reason": "第三方云语音服务",
"usedScene": { "abilities": ["MainAbility"], "when": "inuse" }
}
]
}
}
实际详细应用代码示例实现
1. 调用系统小艺(语音助手)
import featureAbility from '@ohos.ability.featureAbility';
import Want from '@ohos.app.ability.Want';
export class VoiceAssistantUtil {
static startXiaoYi(): void {
let want: Want = {
action: 'ohos.want.action.voiceAssistant',
entities: ['entity.system.home'],
parameters: {
callerToken: featureAbility.getContext().token
}
};
try {
featureAbility.startAbility(want).then((data) => {
console.info('Start XiaoYi success, result:' + JSON.stringify(data));
}).catch((err) => {
console.error('Start XiaoYi failed: ' + JSON.stringify(err));
});
} catch (error) {
console.error('Start XiaoYi exception: ' + JSON.stringify(error));
}
}
}
2. 接收小艺识别结果(需重写 Ability 的 onAbilityResult)
import Ability from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import { BusinessError } from '@ohos.base';
export default class MainAbility extends Ability {
onCreate(want: Want, launchParam: any): void {
console.info('MainAbility onCreate');
}
onWindowStageCreate(windowStage: any): void {
console.info('MainAbility onWindowStageCreate');
}
onAbilityResult(requestCode: number, resultCode: number, data: Want): void {
if (data.parameters && data.parameters.voiceResult) {
const voiceText: string = data.parameters.voiceResult as string;
console.info('Received voice result: ' + voiceText);
// 交给业务逻辑处理
this.handleVoiceCommand(voiceText);
}
}
private handleVoiceCommand(text: string): void {
if (text.includes('打开灯')) {
console.info('执行打开灯操作');
} else if (text.includes('搜索')) {
console.info('执行搜索操作: ' + text);
}
}
}
3. 系统 TTS 播报
import tts from '@ohos.speech.tts';
export class SystemTtsUtil {
private static ttsEngine: tts.TextToSpeechEngine | null = null;
static async init(): Promise<void> {
this.ttsEngine = await tts.createEngine();
await this.ttsEngine.setListener({
onStart: (utteranceId: string) => {
console.info('TTS start: ' + utteranceId);
},
onComplete: (utteranceId: string) => {
console.info('TTS complete: ' + utteranceId);
},
onError: (utteranceId: string, errorCode: number) => {
console.error(`TTS error: ${utteranceId}, code: ${errorCode}`);
}
});
}
static async speak(text: string): Promise<void> {
if (!this.ttsEngine) {
await this.init();
}
const option: tts.SpeakOptions = {
utteranceId: 'utt_' + Date.now(),
locale: 'zh-CN'
};
await this.ttsEngine!.speak(text, option);
}
}
4. 第三方 TTS(示例:讯飞在线 TTS)
import http from '@ohos.net.http';
export class XfyunTtsUtil {
private appId: string = 'your_app_id';
private apiKey: string = 'your_api_key';
private apiSecret: string = 'your_api_secret';
private url: string = 'https://tts-api.xfyun.cn/v2/tts';
async getAuthUrl(): Promise<string> {
// 讯飞鉴权URL生成(简化示例,实际需用HMAC-SHA256签名)
return this.url + '?authorization=xxx&date=xxx';
}
async speak(text: string): Promise<void> {
const authUrl = await this.getAuthUrl();
let httpRequest = http.createHttp();
let response = await httpRequest.request(
authUrl,
{
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'X-Appid': this.appId,
'X-CurTime': String(Math.floor(Date.now() / 1000)),
'X-Param': Base64.encode(JSON.stringify({ auf: 'audio/L16;rate=16000', aue: 'raw', voice_name: 'xiaoyan' }))
},
extraData: `text=${encodeURIComponent(text)}`
}
);
if (response.responseCode === 200) {
// 返回音频二进制,写入AudioPlayer播放
console.info('TTS audio received');
} else {
console.error('TTS request failed: ' + response.result);
}
httpRequest.destroy();
}
}
// 简易Base64(生产环境请用标准库)
class Base64 {
static encode(str: string): string {
// 省略实现
return '';
}
}
5. 第三方 ASR(示例:百度语音识别)
import http from '@ohos.net.http';
import mic from '@ohos.multimedia.microphone';
export class BaiduAsrUtil {
private apiKey: string = 'your_baidu_api_key';
private secretKey: string = 'your_baidu_secret_key';
private tokenUrl: string = 'https://openapi.baidu.com/oauth/2.0/token';
private asrUrl: string = 'http://vop.baidu.com/server_api';
private accessToken: string = '';
async getAccessToken(): Promise<void> {
let httpReq = http.createHttp();
let resp = await httpReq.request(
`${this.tokenUrl}?grant_type=client_credentials&client_id=${this.apiKey}&client_secret=${this.secretKey}`,
{ method: http.RequestMethod.GET }
);
if (resp.responseCode === 200) {
const json = JSON.parse(resp.result as string);
this.accessToken = json.access_token;
}
httpReq.destroy();
}
async recognizePcmFile(path: string): Promise<string> {
if (!this.accessToken) await this.getAccessToken();
// 读取PCM数据(简化示例)
let audioData = readFileSync(path); // 需自行实现文件读取
let httpReq = http.createHttp();
let resp = await httpReq.request(
this.asrUrl,
{
method: http.RequestMethod.POST,
header: { 'Content-Type': 'audio/pcm;rate=16000' },
extraData: audioData,
params: { dev_pid: 1537, token: this.accessToken }
}
);
if (resp.responseCode === 200) {
const json = JSON.parse(resp.result as string);
return json.result ? json.result[0] : '';
}
httpReq.destroy();
return '';
}
}
6. 主页面集成
import { VoiceAssistantUtil } from '../utils/VoiceAssistantUtil';
import { SystemTtsUtil } from '../utils/SystemTtsUtil';
import { BaiduAsrUtil } from '../utils/BaiduAsrUtil';
@Entry
@Component
struct Index {
@State msg: string = '点击开始语音';
build() {
Column({ space: 20 }) {
Text(this.msg).fontSize(20)
Button('调用小艺')
.onClick(() => {
VoiceAssistantUtil.startXiaoYi();
})
Button('系统TTS播报')
.onClick(async () => {
await SystemTtsUtil.init();
await SystemTtsUtil.speak('你好,鸿蒙语音控制已就绪');
})
Button('第三方ASR识别(示例)')
.onClick(async () => {
let asr = new BaiduAsrUtil();
// 需先录音保存为PCM,此处省略录音过程
// let result = await asr.recognizePcmFile('record.pcm');
// this.msg = result;
})
}
.width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
运行结果
-
点击“调用小艺”弹出系统语音助手,说出指令后可在 MainAbility的onAbilityResult收到文本。 -
点击“系统TTS播报”听到合成语音。 -
第三方 ASR/TTS 需联网并在代码中填入有效密钥后可正常工作。
测试步骤以及详细代码
-
配置权限与 SDK,真机运行。 -
测试系统小艺调用与结果回传。 -
测试系统 TTS 播报不同文本。 -
申请第三方云密钥,替换代码中的 appId/apiKey/secretKey,测试网络 ASR/TTS。 -
模拟指令执行(如控制灯、搜索),验证闭环。
部署场景
-
智能家居中枢 App:通过小艺控制全屋鸿蒙设备。 -
车载鸿蒙应用:语音导航与车内设备控制。 -
教育/医疗 App:无障碍语音交互。
疑难解答
|
|
|
|
|---|---|---|
|
|
|
action与权限 |
|
|
|
init并检查系统音量 |
|
|
|
|
|
|
|
|
未来展望
-
接入鸿蒙 AI 语音框架,支持离线大模型识别。 -
与 分布式数据管理 结合,语音指令在多设备间同步状态。 -
支持 情感化 TTS,根据场景调整语调。
技术趋势与挑战
-
趋势:端侧大模型使离线识别与合成成为可能;多模态(语音+视觉)交互兴起。 -
挑战:隐私安全(语音数据不上云)、跨平台引擎一致性、低资源设备性能。
总结
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)