场景介绍
- 将一段不超过10000字符的文本合成为语音并进行播报。
- 场景举例:手机在无网状态下,系统应用无障碍(屏幕朗读)接入文本转语音能力,为视障人士提供播报能力。
开发步骤
-
在使用文本转语音时,将实现文本转语音相关的类添加至工程。
TypeScriptimport { textToSpeech } from '@kit.CoreSpeechKit'; import { BusinessError } from '@kit.BasicServicesKit';
-
调用createEngine接口,创建textToSpeechEngine实例。
createEngine接口提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
TypeScriptlet 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 }; // 调用createEngine方法 textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => { if (!err) { console.info('Succeeded in creating engine'); // 接收创建引擎的实例 ttsEngine = textToSpeechEngine; } else { // 创建引擎失败时返回错误码1003400005,可能原因:引擎不存在、资源不存在、创建引擎超时 console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`); } });
-
得到TextToSpeechEngine实例对象后,实例化SpeakParams对象、SpeakListener对象,并传入待合成及播报的文本originalText,调用speak接口进行播报。
TypeScript// 设置speak的回调信息 let speakListener: textToSpeech.SpeakListener = { // 开始播报回调 onStart(requestId: string, response: textToSpeech.StartResponse) { console.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`); }, // 合成完成及播报完成回调 onComplete(requestId: string, response: textToSpeech.CompleteResponse) { console.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`); }, // 停止播报回调 onStop(requestId: string, response: textToSpeech.StopResponse) { console.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`); }, // 返回音频流 onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) { console.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`); }, // 错误回调 onError(requestId: string, errorCode: number, errorMessage: string) { console.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`); } }; // 设置回调 ttsEngine.setListener(speakListener); let originalText: string = '你好,鸿蒙'; // 设置播报相关参数 let extraParam: Record<string, Object> = {"queueMode": 0, "speed": 1, "volume": 2, "pitch": 1, "languageContext": 'zh-CN', "audioType": "pcm", "soundChannel": 3, "playType": 1 }; let speakParams: textToSpeech.SpeakParams = { requestId: '123456', // requestId在同一实例内仅能用一次,请勿重复设置 extraParams: extraParam }; // 调用播报方法 ttsEngine.speak(originalText, speakParams);
-
(可选)当需要停止合成及播报时,可调用stop接口。
TypeScriptttsEngine.stop();
-
(可选)当需要查询文本转语音服务是否处于忙碌状态时,可调用isBusy接口。
TypeScriptttsEngine.isBusy();
-
(可选)当需要查询支持的语种音色信息时,可调用listVoices接口。
listVoices接口提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
TypeScript// 在组件中声明并初始化字符串voiceInfo @State voiceInfo: string = ""; // 设置查询相关参数 let voicesQuery: textToSpeech.VoiceQuery = { requestId: '12345678', // requestId在同一实例内仅能用一次,请勿重复设置 online: 1 }; // 调用listVoices方法,以callback返回 ttsEngine.listVoices(voicesQuery, (err: BusinessError, voiceInfo: textToSpeech.VoiceInfo[]) => { if (!err) { // 接收目前支持的语种音色等信息 this.voiceInfo = JSON.stringify(voiceInfo); console.info(`Succeeded in listing voices, voiceInfo is ${this.voiceInfo}`); } else { console.error(`Failed to list voices. Code: ${err.code}, message: ${err.message}`); } });
开发实例
点击按钮,播报一段文本。
TypeScript
import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
let ttsEngine: textToSpeech.TextToSpeechEngine;
@Entry
@Component
struct Index {
@State createCount: number = 0;
@State result: boolean = false;
@State voiceInfo: string = "";
@State text: string = "";
@State textContent: string = "";
@State utteranceId: string = "123456";
@State originalText: string = "\n\t\t古人学问无遗力,少壮工夫老始成;\n\t\t" +
"纸上得来终觉浅,绝知此事要躬行。\n\t\t";
@State illegalText: string = "";
build() {
Column() {
Scroll() {
Column() {
TextArea({ placeholder: 'Please enter tts original text', text: `${this.originalText}` })
.margin(20)
.focusable(false)
.border({ width: 5, color: 0x317AE7, radius: 10, style: BorderStyle.Dotted })
.onChange((value: string) => {
this.originalText = value;
console.info(`original text: ${this.originalText}`);
})
Button() {
Text("CreateEngineByCallback")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.createCount++;
console.info(`CreateTtsEngine:createCount:${this.createCount}`);
this.createByCallback();
})
Button() {
Text("speak")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.createCount++;
this.speak();
})
Button() {
Text("listVoicesCallback")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.listVoicesCallback();
})
Button() {
Text("stop")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 停止播报
console.info("Stop button clicked.");
ttsEngine.stop();
})
Button() {
Text("isBusy")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 查询播报状态
let isBusy = ttsEngine.isBusy();
console.info(`isBusy: ${isBusy}`);
})
Button() {
Text("shutdown")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AA7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 释放引擎
ttsEngine.shutdown();
})
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
}
// 创建引擎,通过callback形式返回
// 当引擎不存在、引擎资源不存在、初始化超时,返回错误码1003400005,引擎创建失败
private createByCallback() {
// 设置创建引擎参数
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
};
// 调用createEngine方法
textToSpeech.createEngine(initParamsInfo, (err: BusinessError, textToSpeechEngine: textToSpeech.TextToSpeechEngine) => {
if (!err) {
console.info('Succeeded in creating engine.');
// 接收创建引擎的实例
ttsEngine = textToSpeechEngine;
} else {
// 创建引擎失败时返回错误码1003400005,可能原因:引擎不存在、资源不存在、创建引擎超时
console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
};
// 调用speak播报方法
// 未初始化引擎时调用speak方法,返回错误码1003400007,合成及播报失败
private speak() {
let speakListener: textToSpeech.SpeakListener = {
// 开始播报回调
onStart(requestId: string, response: textToSpeech.StartResponse) {
console.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 完成播报回调
onComplete(requestId: string, response: textToSpeech.CompleteResponse) {
console.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 停止播报完成回调,调用stop方法并完成时会触发此回调
onStop(requestId: string, response: textToSpeech.StopResponse) {
console.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
},
// 返回音频流
onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
console.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
},
// 错误回调,播报过程发生错误时触发此回调
// 未创建引擎时调用speak方法时返回错误码1003400007,合成及播报失败
// 连续调用两次speak,第二次speak会返回错误码1003400006,服务正忙碌
onError(requestId: string, errorCode: number, errorMessage: string) {
console.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
}
};
// 设置回调
ttsEngine.setListener(speakListener);
// 设置播报相关参数
let extraParam: Record<string, Object> = {"queueMode": 0, "speed": 1, "volume": 2, "pitch": 1, "languageContext": 'zh-CN', "audioType": "pcm", "soundChannel": 3, "playType":1}
let speakParams: textToSpeech.SpeakParams = {
requestId: '123456-a', // requestId在同一实例内仅能用一次,请勿重复设置
extraParams: extraParam
};
// 调用speak播报方法
ttsEngine.speak(this.originalText, speakParams);
};
// 查询语种音色信息,以callback形式返回
private listVoicesCallback() {
// 设置查询相关参数
let voicesQuery: textToSpeech.VoiceQuery = {
requestId: '123456-b', // requestId在同一实例内仅能用一次,请勿重复设置
online: 1
};
// 调用listVoices方法,以callback返回语种音色查询结果
ttsEngine.listVoices(voicesQuery, (err: BusinessError, voiceInfo: textToSpeech.VoiceInfo[]) => {
if (!err) {
// 接收目前支持的语种音色等信息
this.voiceInfo = JSON.stringify(voiceInfo);
console.info(`Succeeded in listing voices, voiceInfo is ${voiceInfo}`);
} else {
console.error(`Failed to list voices. Code: ${err.code}, message: ${err.message}`);
}
});
};
}