HarmonyOS Next 入门实战 - 文字转拼音,文字转语音

文字转拼音

安装 pinyin4js 三方库

javascript 复制代码
ohpm install @ohos/pinyin4js

pinyin4js 提供了以下接口:

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

● 文字转拼音首字母

● 简体繁体互转

javascript 复制代码
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)
//风急天高猿萧哀,渚清沙白鸟飞回;

文字转语音

javascript 复制代码
import { textToSpeech } from '@kit.CoreSpeechKit';

创建引擎

textToSpeech 提供 createEngine 方法来创建引擎

javascript 复制代码
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 是否支持后台播报。默认不支持后台播报

javascript 复制代码
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:抢占模式播报。

javascript 复制代码
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)

停止播报

javascript 复制代码
this.ttsEngine.stop()

状态监听

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

javascript 复制代码
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内容包含多个单个汉字和拼音。

javascript 复制代码
@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
  }
}

诗词朗读

javascript 复制代码
@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)
    })
  }
}

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

相关推荐
爱笑的眼睛113 天前
HarmonyOS Next 弹窗系列教程(5)
华为·harmonyos·harmonyos next
HarmonyOS小助手4 天前
【鸿蒙生态学堂04】ArkUI开发基础(上)
harmonyos·鸿蒙·harmonyos next·arkui(方舟ui框架)介绍·使用常用组件构建页面·harmonyos 5.0·鸿蒙5·鸿蒙课程·鸿蒙生态
枫叶丹44 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(三十)
华为·harmonyos·deveco studio·harmonyos next
IUings4 天前
【鸿蒙】HarmonyOS NEXT之如何正常加载地图组件
开发语言·华为·harmonyos·harmonyos next·地图服务·map kit
枫叶丹410 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十八) -> 开发云对象
华为·harmonyos·deveco studio·harmonyos next
枫叶丹412 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十七) -> 开发云函数
华为·harmonyos·deveco studio·harmonyos next
HarmonyOS小助手13 天前
鸿蒙版微信小程序不可用,一文告诉你10分钟修复
harmonyos·鸿蒙·harmonyos next
枫叶丹415 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十六) -> 创建端云一体化开发工程
华为·harmonyos·deveco studio·harmonyos next
枫叶丹418 天前
【HarmonyOS Next之旅】DevEco Studio使用指南(二十五) -> 端云一体化开发 -> 业务介绍(二)
华为·harmonyos·deveco studio·harmonyos next