HarmonyOS鸿蒙Next中AI朗读控件的集成和使用,源码与流程解答
HarmonyOS鸿蒙Next中AI朗读控件的集成和使用,源码与流程解答
鸿蒙AI朗读控件的集成和使用,源码与流程解答
textToSpeech(文本转语音)
文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。
目前本服务支持的语种为中文、英文,支持的音色为聆小珊女声音色、英语(美国)劳拉女声音色、凌飞哲男声音色。
示例:
import { BusinessError } from '@kit.BasicServicesKit';
import { textToSpeech } from '@kit.CoreSpeechKit';
// 创建引擎实例相关参数
let ttsEngine: textToSpeech.TextToSpeechEngine;
let extraParam: Record<string, Object> = {"style": 'interaction-broadcast', "locate": 'CN', "name": 'EngineName'};
let initParamsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN',
person: 0,
online: 1,
extraParams: extraParam
};
// 调用创建引擎实例接口
textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
if (!err) {
console.info('Succeeded in creating engine.');
// 获得引擎实例
ttsEngine = textToSpeechEngine;
} else {
console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
@Entry
@Component
struct Page {
build() {
}
}
开发文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/hms-ai-texttospeech
更多关于HarmonyOS鸿蒙Next中AI朗读控件的集成和使用,源码与流程解答的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
一、结论

鸿蒙系统提供了系统级别的朗读控件,来实现对文本进行朗读的业务需求。不需要复杂的SDK接入和集成,就可实现商业级别的朗读效果。
朗读控件分为听筒组件和朗读控制器,以及朗读面板三部分组成。 朗读面板又分为吸边小面板和全屏朗读面板。
需要注意的是,仅支持中国境内(不包含中国香港、中国澳门、中国台湾)提供服务。并且实时朗读的正文信息长度10000字符以内。
二、代码实现和详细解释
(1)听筒控件TextReaderIcon
提供的听筒控件,可以同步朗读状态,如上动态图所示,有现成的朗读效果,如果业务需要使用,可以用。或者直接跳过也可以,控件参数比较简单
(2)朗读控制器TextReader
TextReader是整个朗读操作逻辑的核心操作对象,系统接口提供了该单例对象。
(3)朗读面板
是个完整的大页面,如gif图所示,可以操控,查看等。
以下为完整的示例DEMO源码,便于理解:
// 导入语音朗读相关的组件和类型
import { TextReader, TextReaderIcon, ReadStateCode } from '@kit.SpeechKit';
@Entry
@Component
struct Index {
/**
* 待加载的文章列表
*/
@State readInfoList: TextReader.ReadInfo[] = [];
/**
* 当前选中的文章
*/
@State selectedReadInfo: TextReader.ReadInfo = this.readInfoList[0];
/**
* 朗读状态
*/
@State readState: ReadStateCode = ReadStateCode.WAITING;
/**
* 初始化状态标记
*/
@State isInit: boolean = false;
// 组件即将显示时触发
async aboutToAppear(){
/**
* 模拟加载文章数据
*/
let readInfoList: TextReader.ReadInfo[] = [{
id: '001',
title: {
text:'水调歌头.明月几时有',
isClickable:true
},
author:{
text:'宋.苏轼',
isClickable:true
},
date: {
text:'2024/01/01',
isClickable:false
},
bodyInfo: '明月几时有?把酒问青天。不知天上宫阙,今夕是何年?'
}];
// 更新状态变量
this.readInfoList = readInfoList;
this.selectedReadInfo = this.readInfoList[0];
// 初始化朗读组件
this.init();
}
/**
* 初始化朗读组件
*/
async init() {
// 朗读参数配置
const readerParam: TextReader.ReaderParam = {
isVoiceBrandVisible: true, // 显示品牌信息
businessBrandInfo: {
panelName: '小艺朗读', // 面板名称
panelIcon: $r('app.media.startIcon') // 面板图标
}
}
try {
// 获取上下文
let context: Context | undefined = this.getUIContext().getHostContext()
if (context) {
// 初始化朗读组件
await TextReader.init(context, readerParam);
this.isInit = true; // 标记初始化完成
this.setActionListener(); // 设置事件监听
}
} catch (err) {
// 初始化失败时打印错误信息
console.error(`TextReader failed to init. Code: ${err.code}, message: ${err.message}`);
}
}
// 设置朗读事件监听
setActionListener() {
// 监听朗读状态变化
TextReader.on('stateChange', (state: TextReader.ReadState) => {
this.onStateChanged(state);
});
// 监听加载更多请求
TextReader.on('requestMore', () => {
TextReader.loadMore([], true);
})
}
// 处理朗读状态变化
onStateChanged = (state: TextReader.ReadState) => {
// 只处理当前选中文章的状态变化
if (this.selectedReadInfo?.id === state.id) {
this.readState = state.state;
} else {
this.readState = ReadStateCode.WAITING;
}
}
// 构建UI界面
build() {
Column() {
// 朗读状态图标
TextReaderIcon({ readState: this.readState })
.margin({ right: 20 })
.width(32)
.height(32)
.onClick(async () => {
// 点击图标时开始朗读
try {
await TextReader.start(this.readInfoList, this.selectedReadInfo?.id);
} catch (err) {
// 朗读失败时打印错误信息
console.error(`TextReader failed to start. Code: ${err.code}, message: ${err.message}`);
}
})
}
.height('100%')
}
}
三、工具类封装源码共享:
封装ReaderIconView朗读图标,联动管理类的朗读状态,即插即用。
import { ReadStateCode, TextReaderIcon } from "@kit.SpeechKit";
import { TextReaderMgr, TextReaderRegister } from "../mgr/TextReaderMgr";
import { common } from "@kit.AbilityKit";
@Component
export struct ReaderIconView {
private TAG: string = "ReaderIconView";
/**
* 朗读状态
*/
@State readState: ReadStateCode = ReadStateCode.WAITING;
private mTextReaderRegister: TextReaderRegister = {
onStateChange: (state: ReadStateCode): void => {
this.readState = state;
console.log(this.TAG, "mTextReaderRegister onStateChange state: " + state);
}
}
aboutToAppear(): void {
const context = getContext(this) as common.UIAbilityContext;
TextReaderMgr.Ins().initReader(context, null, null, this.mTextReaderRegister);
console.log(this.TAG, " aboutToAppear initReader done");
}
build() {
TextReaderIcon({ readState: this.readState })
.width("100%")
.height("100%")
}
}
封装单例朗读管理类,用于便捷操作朗读相关接口,封装细节,方便快速调用:
import { ReadStateCode, TextReader } from "@kit.SpeechKit";
/**
* 初始化配置对象
*/
export class TextReaderInitData {
// 全屏面板标题名称
panelName: string = "";
// 是否需要吸边小面板
isMinibarNeeded: boolean = true;
// 是否需要全屏面板
isPanelNeeded: boolean = true;
}
/**
* 控制器操作回调
*/
export interface TextReaderCall {
onReady: () => void
onInitFail: (err: string) => void
onFail: (err: string) => void
}
/**
* 监听回调
*/
export interface TextReaderRegister {
onStateChange: (state: ReadStateCode) => void
}
/**
* 错误码
*/
export enum TextReaderFail {
UnInit = "0",
TextReaderInfoNULL = "1"
}
/**
* 文本朗读对象
*/
export class TextReaderInfo {
title: string = "";
content: string = "";
author?: string = "";
date?: string = "";
}
/**
* 文本朗读管理类
*/
export class TextReaderMgr {
private TAG: string = "TextReaderMgr";
private static mTextReaderMgr: TextReaderMgr | null = null;
private mInit: boolean = false;
private mTextReaderCall: TextReaderCall | null = null;
private mTextReaderInitData: TextReaderInitData | null = null;
private mTextReaderRegister: TextReaderRegister | null = null;
private mCurrentReadInfo: TextReader.ReadInfo | null = null;
public static Ins() {
if (!TextReaderMgr.mTextReaderMgr) {
TextReaderMgr.mTextReaderMgr = new TextReaderMgr();
}
return TextReaderMgr.mTextReaderMgr;
}
/**
* 设置朗读事件监听
*/
private setActionListener() {
// 监听朗读状态变化
TextReader.on('stateChange', (state: TextReader.ReadState) => {
let readState: ReadStateCode = ReadStateCode.WAITING;
if (this.mCurrentReadInfo?.id === state.id) {
readState = state.state;
} else {
readState = ReadStateCode.WAITING;
}
this.mTextReaderRegister?.onStateChange(readState);
});
// 监听加载更多请求
TextReader.on('requestMore', (callbackStr) => {
console.log(this.TAG, " callbackStr: " + callbackStr);
let readInfoList: TextReader.ReadInfo[] = [{
id: '002',
title: {
text: '水调歌头.明月几时有2',
isClickable: true
},
author: {
text: '宋.苏轼2',
isClickable: true
},
date: {
text: '2025/02/02',
isClickable: false
},
bodyInfo: '2明月几时有?把酒问青天。不知天上宫阙,今夕是何年?'
}];
TextReader.loadMore(readInfoList, true);
})
}
/**
* 初始化朗读播放控件
*/
public async initReader(context: Context, callback?: TextReaderCall | null, data?: TextReaderInitData | null,
register?: TextReaderRegister) {
this.mTextReaderCall = callback ?? null;
this.mTextReaderInitData = data ?? null;
this.mTextReaderRegister = register ?? null;
// 朗读参数配置
const readerParam: TextReader.ReaderParam = {
isVoiceBrandVisible: data?.panelName == "" ? false : true ?? true, // 显示品牌信息
businessBrandInfo: {
panelName: data?.panelName == "" ? '朗读' : data?.panelName ?? '朗读', // 面板名称
},
isMinibarNeeded: data?.isMinibarNeeded ?? true
}
try {
if (context) {
// 初始化朗读组件
await TextReader.init(context, readerParam);
this.mInit = true; // 标记初始化完成
this.setActionListener(); // 设置事件监听
this.mTextReaderCall?.onReady();
}
} catch (err) {
// 初始化失败时打印错误信息
console.error(this.TAG, `TextReader failed to init. Code: ${err.code}, message: ${err.message}`);
this.mTextReaderCall?.onInitFail(JSON.stringify(err));
}
}
/**
* 文本朗读播放接口(不显示字幕全屏面板和吸边小面板,直接朗读文本)
* @param content 实时朗读的正文信息(长度10000字符以内)
*/
public async startContent(context: Context, content: string) {
await this.initReader(context);
let readInfoList: TextReader.ReadInfo[] = [{
id: '0',
title: {
text: '',
isClickable: true
},
bodyInfo: content
}];
this.mCurrentReadInfo = readInfoList[0];
await TextReader.start(readInfoList, this.mCurrentReadInfo.id);
TextReader.hidePanel();
}
/**
* 启动朗读
* @param infoArr
*/
public async start(infoArr: TextReaderInfo[]) {
// 判断当前是否初始化成功过
if (!this.mInit) {
console.error(this.TAG, "start error ! mInit false !");
this.mTextReaderCall?.onFail(TextReaderFail.UnInit);
return;
}
if (!infoArr) {
console.error(this.TAG, "start error ! infoArr null !");
this.mTextReaderCall?.onFail(TextReaderFail.TextReaderInfoNULL);
return;
}
// 朗读启动配置
const startParams: TextReader.StartParams = {
isMinibarHidden: this.mTextReaderInitData?.isMinibarNeeded ?? true,
}
// 填充朗读内容
let readInfoList: TextReader.ReadInfo[] = [];
for (let index = 0; index < infoArr.length; index++) {
const info = infoArr[index];
let tempInfo: TextReader.ReadInfo = {
id: " " + index,
title: {
text: info.title,
isClickable: true,
},
bodyInfo: info.content,
date: {
text: info.author ?? "",
isClickable: true,
},
author: {
text: info.author ?? "",
isClickable: true,
}
}
readInfoList.push(tempInfo);
}
this.mCurrentReadInfo = readInfoList[0];
// 启动朗读
await TextReader.start(readInfoList, this.mCurrentReadInfo.id, startParams);
}
}
在HarmonyOS Next中,AI朗读功能主要通过TextToSpeech(TTS)引擎实现,而非一个独立的UI控件。其核心是系统服务,开发者可通过API调用实现文本朗读。以下是集成与使用的关键流程和源码示例:
1. 权限与依赖
- 权限声明:在
module.json5文件中添加ohos.permission.USE_TTS权限。
"requestPermissions": [
{
"name": "ohos.permission.USE_TTS"
}
]
- SDK依赖:确保API版本≥10(HarmonyOS Next)。
2. 核心API与流程
初始化TTS引擎
import tts from '@ohos.tts';
// 获取TTS实例
let ttsEngine = tts.getTtsEngine();
配置参数与播放
// 设置朗读参数(语速、音调等)
let params: tts.TtsParams = {
volume: 0.8, // 音量(0.0-1.0)
speed: 1.0, // 语速(0.5-2.0)
pitch: 1.0 // 音调(0.5-2.0)
};
// 播放文本
ttsEngine.speak('需要朗读的文本', params).then(() => {
console.info('朗读开始');
}).catch((err: Error) => {
console.error(`朗读失败: ${err.message}`);
});
事件监听
// 监听状态变化
ttsEngine.on('start', () => {
console.info('播放开始');
});
ttsEngine.on('finish', () => {
console.info('播放结束');
});
ttsEngine.on('error', (err: Error) => {
console.error(`播放错误: ${err.message}`);
});
流程控制
// 暂停/恢复/停止
ttsEngine.pause();
ttsEngine.resume();
ttsEngine.stop();
// 释放资源(页面销毁时调用)
ttsEngine.release();
3. 自定义UI控件封装示例
可基于TTS服务封装可复用的朗读按钮组件:
// TtsButton.ets
@Component
export struct TtsButton {
private text: string = '';
private isPlaying: boolean = false;
build() {
Button(this.isPlaying ? '停止朗读' : '开始朗读')
.onClick(() => {
if (this.isPlaying) {
tts.getTtsEngine().stop();
} else {
tts.getTtsEngine().speak(this.text);
}
this.isPlaying = !this.isPlaying;
})
}
}
4. 关键注意事项
- 引擎可用性检查:调用前通过
ttsEngine.isSupport()验证设备支持情况。 - 多语言支持:通过
ttsEngine.getVoices()获取支持的语音包,设置params.language参数。 - 后台播放:需申请
ohos.permission.KEEP_BACKGROUND_RUNNING权限并配置长时任务。
5. 完整调用链示例
// 1. 初始化并检查支持
let engine = tts.getTtsEngine();
if (!engine.isSupport()) {
console.error('设备不支持TTS');
return;
}
// 2. 设置参数并播放
engine.speak('HarmonyOS Next AI朗读示例', {
speed: 1.2,
language: 'zh-CN'
});
// 3. 管理生命周期
// 页面隐藏时暂停
// 页面销毁时调用engine.release()
该实现直接调用系统TTS服务,无需引入第三方库。注意参数配置需在设备支持的范围内,异常处理需覆盖网络依赖(在线语音包下载)场景。


