文章目录
- 一、Core Speech Kit简介
- 场景介绍
- 约束与限制
- 二、文本转语音
- 1. 场景介绍
- 2. 约束与限制
- 3. 开发步骤
- 4. 设置播报策略
- 设置数字播报策略
- 插入静音停顿
- 指定汉字发音
- 5. 开发实例
- 三、语音识别
- 约束与限制
- 开发步骤
- 开发实例
一、Core Speech Kit简介
Core Speech Kit(基础语音服务)集成了语音类基础AI能力,包括文本转语音(TextToSpeech)及语音识别(SpeechRecognizer)能力,便于用户与设备进行互动,实现将实时输入的语音与文本之间相互转换。
场景介绍
- 文本转语音:将一段不超过10000字符的文本合成为语音并进行播报。
- 语音识别:将一段音频信息(短语音模式不超过60s,长语音模式不超过8h)转换为文本,可以将pcm音频文件或者实时语音转换为文字。
约束与限制
AI能力 | 约束 |
---|---|
文本转语音 | 1.支持的语种类型:中文。(简体中文、繁体中文、中文语境下的英文) 2. 支持的音色类型:聆小珊女声音色。3. 文本长度:不超过10000字符。 |
语音识别 | 1. 支持的语种类型:中文普通话。2. 支持的模型类型:离线。3. 语音时长:短语音模式不超过60s,长语音模式不超过8h。 |
二、文本转语音
Core Speech Kit支持将一篇不超过10000字符的中文文本(简体中文、繁体中文、数字、中文语境下的英文)合成为语音,并以聆小珊女声音色中文播报。
开发者可对播报的策略进行设置,包括单词播报、数字播报、静音停顿、汉字发音策略。
1. 场景介绍
手机/平板等设备在无网状态下,系统应用无障碍(屏幕朗读)接入文本转语音能力,为视障人士或不方便阅读场景提供播报能力。
2. 约束与限制
该能力当前不支持模拟器。
3. 开发步骤
- 在使用文本转语音时,将实现文本转语音相关的类添加至工程。
import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
- 调用createEngine接口,创建textToSpeechEngine实例。
createEngine接口提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
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
};// 调用createEngine方法
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}.`);}
});
- 得到TextToSpeechEngine实例对象后,实例化SpeakParams对象、SpeakListener对象,并传入待合成及播报的文本originalText,调用speak接口进行播报。
// 设置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 = 'Hello HarmonyOS';
// 设置播报相关参数
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
};
// 调用播报方法
// 开发者可以通过修改speakParams主动设置播报策略
ttsEngine.speak(originalText, speakParams);
- (可选)当需要停止合成及播报时,可调用stop接口。
ttsEngine.stop();
- (可选)当需要查询文本转语音服务是否处于忙碌状态时,可调用isBusy接口。
ttsEngine.isBusy();
- (可选)当需要查询支持的语种音色信息时,可调用listVoices接口。
listVoices接口提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
// 在组件中声明并初始化字符串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}`);}
});
4. 设置播报策略
由于不同场景下,模型自动判断所选择的播报策略可能与实际需求不同,此章节提供对于播报策略进行主动设置的方法。
说明
以下取值说明均为有效取值,若所使用的数值在有效取值之外则播报结果可能与预期不符,并产生错误的播报结果。
文本格式:[hN] (N=0/1/2)
N取值说明:
取值 | 说明 |
---|---|
0 | 智能判断单词播放方式。默认值为0。 |
1 | 逐个字母进行播报。 |
2 | 以单词方式进行播报。 |
文本示例:
"hello[h1] world"
hello使用单词发音,world及后续单词将会逐个字母进行发音。
设置数字播报策略
格式:[nN] (N=0/1/2)
取值 | 说明 |
---|---|
0 | 智能判断数字处理策略。默认值为0。 |
1 | 作为号码逐个数字播报。 |
2 | 作为数值播报。超过18位数字不支持,自动按逐个数字进行播报。 |
文本示例:
"[n2]123[n1]456[n0]"
其中,123将会按照数值播报,456则会按照号码播报,而后的文本中的数字,均会自动判断。
插入静音停顿
格式:[pN]
描述:N为无符号整数,单位为ms。
文本示例:
"你好[RZer]阅读者"
该句播报时,将会在“你好”后插入500ms的静音停顿。
指定汉字发音
汉字声调用后接一位数字1~5分别表示阴平、阳平、上声、去声和轻声5个声调。
格式:[=MN]
描述:M表示拼音,N表示声调。
取值 | 说明 |
---|---|
1 | 阴平 |
2 | 阳平 |
3 | 上声 |
4 | 去声 |
5 | 轻声 |
文本示例:
"着[=zhuo2]手"
“着”字将读作“zhuó”。
5. 开发实例
点击按钮,播报一段文本
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%").<