文字转拼音

安装 pinyin4js 三方库

ohpm install @ohos/pinyin4js

pinyin4js 提供了以下接口:

● 文字转拼音(带声调和不带声调)

● 文字转拼音首字母

● 简体繁体互转

let rawText = "风急天高猿萧哀,渚清沙白鸟飞回;"
let pinyin1: string =
pinyin4js.convertToPinyinString(rawText, " ", pinyin4js.WITH_TONE_MARK)
//fēng jí tiān gāo yuán xiāo āi , zhǔ qīng shā bái niǎo fēi huí ;
let pinyin2: string = pinyin4js.convertToPinyinString(rawText, " ", pinyin4js.WITHOUT_TONE)
//feng ji tian gao yuan xiao ai , zhu qing sha bai niao fei hui ;
let pinyinFirst: string = pinyin4js.getShortPinyin(rawText)
//fjtgyxa,zqsbnfh;
let sTot: string = pinyin4js.convertToTraditionalChinese(rawText)
//風急天高猿蕭哀,渚清沙白鳥飛回;
let tTos: string = pinyin4js.convertToSimplifiedChinese(sTot)
//风急天高猿萧哀,渚清沙白鸟飞回;

文字转语音

import { textToSpeech } from '@kit.CoreSpeechKit';

创建引擎

textToSpeech 提供 createEngine 方法来创建引擎

function createEngine(createEngineParams: CreateEngineParams): Promise<TextToSpeechEngine>;

CreateEngineParams 包含如下字段

● language:语种,当前仅支持“zh-CN”中文

● person:音色。0为聆小珊女声音色,当前仅支持聆小珊女声音色。

● online:模式。0为在线,目前不支持;1为离线,当前仅支持离线模式

● extraParams:扩展参数

其中 extraParams 扩展参数包含如下字段

● style :string 风格。可选,不设置时默认为“interaction-broadcast”,当前仅支持“interaction-broadcast”广播风格。

● locate:string 区域信息。可选,不设置时默认为“CN”

● name:string 引擎名称。可选,引擎名称,不设置时默认为空

● isBackStage:boolean 是否支持后台播报。默认不支持后台播报

let extraParams: Record<string, Object> = {
"style": 'interaction-broadcast',
"locate": 'CN',
"name": '',
"isBackStage": true
}
let paramsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN',
person: 0,
online: 1,
extraParams: extraParams
}
textToSpeech.createEngine(paramsInfo).then((value) => {
this.ttsEngine = value
}).catch((err: BusinessError) => { })

文本播报

创建引擎后,通过调用引擎对象的 speak 方法进行文本播报

TextToSpeechEngine.speak(text: string, speakParams: SpeakParams): void;

● text:待播报的文本

● speakParams:合成播报音频的相关参数

speakParams 包含如下字段

● requestId:合成播报ID,全局不允许重复

● extraParams

○ speed:语速,可选,支持范围[0.5-2],不传参时默认为1

○ volume:音量,可选,支持范围[0-2],不传参时默认为1,

○ pitch:音调。可选,支持范围[0.5-2],不传参时默认为1,

○ languageContext:语境,播放阿拉伯数字用的语种。可选,当前仅支持“zh-CN”中文,默认“zh-CN”

○ audioType:音频类型。可选,当前仅支持“pcm”且为默认

○ playType:合成类型。0:仅合成不播报,返回音频流。1:合成与播报不返回音频流(默认)

○ soundChannel:播报通道,默认为3语音助手通道

○ queueMode:播报模式。可选,0:排队模式播报(默认)。1:抢占模式播报。

let extraParams: Record<string, Object> = {
"speed": 1,
"volume": 1,
"pitch": 1,
"languageContext": 'zh-CN',
"audioType": 'pcm',
"playType": 1,
"soundChannel": 3,
"queueMode": 1
}
let params: textToSpeech.SpeakParams = {
requestId: util.generateRandomUUID(),
extraParams: extraParams
}
this.ttsEngine?.speak(text, params)

停止播报

this.ttsEngine.stop()

状态监听

设置播报监听,可以收到开始,完成,暂停,播报信息,错误等状态回调

let listener: textToSpeech.SpeakListener = {
//播报开始时,回调此接口
onStart: (requestId: string, response: textToSpeech.StartResponse): void => { },
//合成或播报结束后分别回调此接口,CompleteResponse.type = 0:合成结束。1:播报结束。
onComplete: (requestId: string, response: textToSpeech.CompleteResponse): void => { },
//调用stop()方法时,回调此接口
onStop: (requestId: string, response: textToSpeech.StopResponse): void => { },
//合成播报过程中,出现错误时回调
onError: (requestId: string, errorCode: number, errorMessage: string): void => { },
//合成播报过程中回调此接口,返回请求ID,音频流信息,音频附加信息如格式、时长等
onData:(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) :void => { }
}
this.ttsEngine?.setListener(listener)

播报策略

● 单词播报方式:[hN] (N=0/1/2) 0-智能判断,1-逐个字母播报,2-单词播报 例如:hello[h1] world

● 数字播报策略:[nN] (N=0/1/2) 0-智能判断,1-逐个号码播报,2-作为数值播报 例如:[n2]123[n1]456[n0]

● 静音停顿:[pN] N为无符号整数,单位为ms,例如:你好[p500]小艺

● 指定汉字发音:[=MN] M表示拼音,N表示声调,1~5分别表示阴平、阳平、上声、去声和轻声5个声调。例如:着[=zhuo2]手

诗词拼音展示

创建拼音展示组件

此组件使用Column和Flex组件来实现,每个Flex组件为一个段落,Flex内容包含多个单个汉字和拼音。

@Component
struct PinyinView {
@Prop text: string
@Prop pinyin: string
private textArray: Array<string> = []
private pinyinArray: Array<Array<string>> = [] aboutToAppear(): void {
this.textArray = this.text.split("\n")
let pinyinRow = this.pinyin.split("\n")
for (let row of pinyinRow) {
this.pinyinArray.push(row.trim().split(" "))
}
} build() {
Column() {
ForEach(this.textArray, (item: string, rowIndex) => {
if (item) {
Flex({
direction: FlexDirection.Row,
wrap: FlexWrap.Wrap,
space: { cross: LengthMetrics.vp(8) }
}) {
ForEach(item.split(""), (item1: string, index) => {
this.WordView(item1, this.pinyinArray[rowIndex][index])
})
}.width('90%').margin({ top: rowIndex == 0 ? 0 : 8 })
} else {
Row().width('100%').height(22)
}
})
}
} @Builder
WordView(text: string, pinyin: string) {
Column() {
Text(pinyin)
.fontSize(12)
.fontColor(Theme.Color.textSecondary)
.padding({ top: 3, bottom: 3 })
.visibility(this.isHanZi(text) ? Visibility.Visible : Visibility.Hidden)
Text(text)
.fontSize(20)
.fontColor(Theme.Color.textPrimary)
.margin({ top: 3 })
}.width("12.5%")
} isHanZi(text: string) {
return text.charCodeAt(0) >= 0x4e00 && text.charCodeAt(0) <= 0x9fa5
}
}

诗词朗读

@ComponentV2
export struct PoetryDetailPage {
@Local soundPlayStatus: boolean = false
ttsEngine: textToSpeech.TextToSpeechEngine | null = null aboutToDisappear(): void {
if (this.ttsEngine) {
this.ttsEngine.stop()
this.ttsEngine.shutdown()
}
} initEngine(): Promise<void> {
return new Promise((resolve, reject) => {
if (this.ttsEngine == null) {
let extraParams: Record<string, Object> = {
"style": 'interaction-broadcast',
"locate": 'CN',
"name": '',
"isBackStage": true
}
let paramsInfo: textToSpeech.CreateEngineParams = {
language: 'zh-CN',
person: 0,
online: 1,
extraParams: extraParams
}
textToSpeech.createEngine(paramsInfo).then((value) => {
this.ttsEngine = value
resolve()
}).catch((err: BusinessError) => {
Toast.show(err.message)
reject()
})
} else {
resolve()
}
})
} speak() {
if (this.ttsEngine && this.ttsEngine.isBusy()) {
this.ttsEngine.stop()
return
}
this.initEngine().then(() => {
let listener: textToSpeech.SpeakListener = {
onStart: (requestId: string, response: textToSpeech.StartResponse): void => {
this.soundPlayStatus = true
},
onComplete: (requestId: string, response: textToSpeech.CompleteResponse): void => {
if (response.type == 1) {
this.soundPlayStatus = false
}
},
onStop: (requestId: string, response: textToSpeech.StopResponse): void => {
this.soundPlayStatus = false
},
onError: (requestId: string, errorCode: number, errorMessage: string): void => {
this.soundPlayStatus = false
}
}
this.ttsEngine?.setListener(listener)
let extraParams: Record<string, Object> = {
"speed": 1,
"volume": 1,
"pitch": 1,
"languageContext": 'zh-CN',
"audioType": 'pcm',
"playType": 1,
"soundChannel": 3,
"queueMode": 1
}
let params: textToSpeech.SpeakParams = {
requestId: util.generateRandomUUID(),
extraParams: extraParams
}
let speakText =
`${this.poetry?.title}[p200]
${this.poetry?.dynasty}[p50]${this.poetry?.author}[p200]
${this.poetry?.text}` this.ttsEngine?.speak(speakText, params)
})
}
}

本文的技术设计和实现都是基于作者工作中的经验总结,如有错误,请留言指正,谢谢。

HarmonyOS Next 入门实战 - 文字转拼音,文字转语音的更多相关文章

  1. javaScript对文字按照拼音排序

    <title>JavaScript对文字按照拼音排序</title> <SCRIPT type="text/javascript"> funct ...

  2. Atitit s2018.2 s2 doc list on home ntpc.docx  \Atiitt uke制度体系 法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别 讯飞科大 语音云.docx \Atitit 代码托管与虚拟主机.docx \Atitit 企业文化 每日心灵 鸡汤 值班 发布.docx \Atitit 几大研发体系对比 Stage-Gat

    Atitit s2018.2 s2 doc list on home ntpc.docx \Atiitt uke制度体系  法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别   ...

  3. 向大家介绍我的新书:《基于股票大数据分析的Python入门实战》

    我在公司里做了一段时间Python数据分析和机器学习的工作后,就尝试着写一本Python数据分析方面的书.正好去年有段时间股票题材比较火,就在清华出版社夏老师指导下构思了这本书.在这段特殊时期内,夏老 ...

  4. css图片+文字浮动(文字包围效果)

    css图片+文字浮动(文字包围效果): 在网页中,我们有时想实现这个效果,但是 <div id="test"> <img src="gdimages/0 ...

  5. Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...

  6. 003-Tuple、Array、Map与文件操作入门实战

    003-Tuple.Array.Map与文件操作入门实战 Tuple 各个元素可以类型不同 注意索引的方式 下标从1开始 灵活 Array 注意for循环的until用法 数组的索引方式 上面的for ...

  7. Scala深入浅出实战经典-----002Scala函数定义、流程控制、异常处理入门实战

    002-Scala函数定义.流程控制.异常处理入门实战 Scala函数定义 语句结束无分号 定义无参函数 def 函数名称(参数名称:参数类型)[:Unit=]{ 函数体 } 老师的代码 我的实际代码 ...

  8. Spark入门实战系列--1.Spark及其生态圈简介

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .简介 1.1 Spark简介 年6月进入Apache成为孵化项目,8个月后成为Apache ...

  9. Spark入门实战系列--2.Spark编译与部署(上)--基础环境搭建

    [注] 1.该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取: 2.Spark编译与部署将以CentOS 64位操作系统为基础,主要是考虑到实际应用 ...

  10. Spark入门实战系列--2.Spark编译与部署(中)--Hadoop编译安装

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .编译Hadooop 1.1 搭建环境 1.1.1 安装并设置maven 1. 下载mave ...

随机推荐

  1. C#上位机与PLC通信心跳的实现方法

    -Begin- 大家好!我是付工.众所周知,在工业自动化控制系统中,上位机与下位机之间的通信是实现自动化生产的关键环节之一.为了确保通信的稳定性和可靠性,我们通用会采用一种被称为[心跳机制]的方法,它 ...

  2. C# 开源浏览器性能提升,体验Chrome级速度

    前言 使用 C# 和 CefSharp 开发的全功能网页浏览器. 项目介绍 SharpBrowser 是目前最快的开源 C# 网页浏览器! 采用了轻量级的 CEF 渲染器,在呈现网页时甚至比 Goog ...

  3. [OI] 可持久化数据结构

    学了一年 OI 才看懂这句话: \(\log n\) 是以什么为底的? 其实没什么区别 因为我们自动忽略常数,因此 \(\log_{a}n=\frac{\log_{x}n}{\log_{x}a}=\l ...

  4. [OI] 珂朵莉树

    对于一个序列,它有较多重复元素,并且题目需要维护区间修改,维护区间信息,维护整块值域信息的,那么就可以考虑珂朵莉树解决. 主要思想 珂朵莉树将全部相同的颜色块压缩为一组,如对于下述序列: 1 1 1 ...

  5. request和response请求包中的各项解释

    Request Response

  6. uniapp中前端canvas合成图片使用详解

    项目开发中用到了定位打卡,保存当前位置到上传图片的功能.刚开始想着后端人员合成,前端上传经纬度.位置信息和图片就OK,没想到后端人员以使用项目中现有的组件为借口,让前端合成图片,造成前端工作量大增,再 ...

  7. ios中文件夹文件的创建和删除

    //1.文件夹.文件的创建和删除 NSFileManager *fileManager=[NSFileManager defaultManager]; NSString *filePath=@&quo ...

  8. 如何让img图片居中

    说明:img是行内块元素,用一个盒子(父元素)嵌套img(子元素) text-align:center;可以让父元素为块元素的行内块或行内元素水平居中: vaertical-align:middle; ...

  9. 我们如何在 vue 应用我们的权限

    权限可以分为用户权限和按钮权限: 用户权限,让不同的用户拥有不同的路由映射 ,具体实现方法: 1. 初始化路由实例的时候,只把静态路由规则注入 ,不要注入动态路由规则 : 2. 用户登录的时候,根据返 ...

  10. 10 Self-Attention(自注意力机制)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...