Location>code7788 >text

HarmonyOS Next Getting Started - Text to Pinyin, Text to Speech

Popularity:529 ℃/2024-12-17 11:52:09

text-to-pinyin conversion

Install the pinyin4js tripartite library

ohpm install @ohos/pinyin4js

pinyin4js provides the following interfaces:
:: Text-to-pinyin (with and without tones)
:: Text-to-Pinyin Initialization
:: Simplified and traditional conversions

let rawText = "The wind and the sky are high and the apes are sad, the sand is clear and the birds fly back;"
let pinyin1: string =
  (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 = (rawText, " ", pinyin4js.WITHOUT_TONE)
//feng ji tian gao yuan xiao ai , zhu qing sha bai niao fei hui ;
let pinyinFirst: string = (rawText)
//fjtgyxa, zqsbnfh;
let sTot: string = (rawText)
//The wind and the sky are high and the apes are sad, the islets are clear and the sand is white and the birds fly back;
let tTos: string = (sTot)
//The wind rushes and the sky is high and the apes are sad, the islet is clear and the sand is white and the birds fly back;

text-to-speech

import { textToSpeech } from '@';

Creating an Engine
textToSpeech provides the createEngine method to create the engine.

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

CreateEngineParams contains the following fields
● language: language, currently only supports "zh-CN" Chinese.
● person: timbre. 0 is the color of the female voice of Listening Xiao Shan, and only the female voice of Listening Xiao Shan is supported at the moment.
● online: mode. 0 is online, currently not supported; 1 is offline, currently only supports offline mode
● extraParams: extended parameters
where the extraParams extension parameter contains the following fields
● style: string style. Optional, defaults to "action-broadcast" if not set, currently only "action-broadcast" broadcast style is supported.
● locate: string locale information. Optional, defaults to "CN" if not set.
● name: string Engine name. Optional, the name of the engine, default is null if not set.
● isBackStage: boolean Whether backstage broadcasting is supported. The default does not support backstage broadcasting

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

})

text broadcast
After the engine is created, the text is broadcast by calling the speak method of the engine object.
(text: string, speakParams: SpeakParams): void;
● text: text to be broadcast
● speakParams: parameters related to synthesized broadcast audio
speakParams contains the following fields
● requestId: synthesized broadcast ID, globally not allowed to be repeated
● extraParams
○ speed: speed of speech, optional, support range [0.5-2], default is 1 when no parameter is passed.
○ volume: volume, optional, support range [0-2], default is 1 when no parameter is passed.
○ pitch: pitch. Optional, support range [0.5-2], default is 1 when no parameter is passed.
○ languageContext: the context, the language used to play Arabic numerals. Optional, currently only support "zh-CN" Chinese, default "zh-CN".
audioType: audio type. Optional, currently only supports "pcm" and is the default.
○ playType: synthesis type. 0: synthesize only without playback, return audio stream. 1: synthesize with playback without return audio stream (default)
○ soundChannel: broadcast channel, default is 3 voice assistant channel
○ queueMode: broadcast mode. Optional, 0: queue mode broadcast (default). 1: preemptive mode broadcast.

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

Go off the air.

()

stateful listening
Setting up a broadcast listener to receive status callbacks such as start, finish, pause, broadcast message, error, etc.

let listener: = {
  // This interface is called when the broadcast starts.
  onStart: (requestId: string, response: ): void => {

  }, //callback when compositing or broadcasting finishes, respectively.
  // This interface is called when the compositing or broadcasting is finished, respectively, = 0: Compositing is finished. 1: Broadcasting is finished.
  onComplete: (requestId: string, response: ): void => {

  },
  // Callback this interface when the stop() method is called
  onStop: (requestId: string, response: ): void => {

  }, //Callback this interface when calling the stop() method.
  // Called when an error occurs during synthesized broadcasting.
  onError: (requestId: string, errorCode: number, errorMessage: string): void => {

  }, // Callback during synthesized announcements.
  // Callback this interface during the synthesized broadcast to return the request ID, audio stream information, and additional audio information such as format, duration, etc.
  onData:(requestId: string, audio: ArrayBuffer, response: ) :void => {

  }
}
? .setListener(listener)

Broadcast Strategy
● Word announcement mode: [hN] (N=0/1/2) 0-intelligent judgment, 1-letter-by-letter announcement, 2-word announcement Example: hello [h1] world
● Number broadcast strategy: [nN] (N=0/1/2) 0-intelligent judgment, 1-number-by-number broadcast, 2-as numerical value e.g. [n2]123[n1]456[n0]
● Mute pause: [pN] N is an unsigned integer in ms, e.g. Hello [p500] Xiao Yi
● Specify the pronunciation of a Chinese character: [=MN] M for pinyin, N for tone, and 1~5 for the 5 tones of yinping, yangping, supersonic, declination, and soft tone, respectively. For example: (chess) move [=zhuo2] hand

Poetry Pinyin Showcase

Create Pinyin Display Component
This component is implemented using Column and Flex components, each Flex component is a paragraph and the Flex content contains multiple individual Chinese characters and Pinyin.

@Component
struct PinyinView {
  @Prop text: string
  @Prop pinyin: string
  private textArray: Array<string> = []
  private pinyinArray: Array<Array<string>> = []

  aboutToAppear(): void {
     = ("\n")
    let pinyinRow = ("\n")
    for (let row of pinyinRow) {
      (().split(" "))
    }
  }

  build() {
    Column() {
      ForEach(, (item: string, rowIndex) => {
        if (item) {
          Flex({
            direction: ,
            wrap: ,
            space: { cross: (8) }
          }) {
            ForEach((""), (item1: string, index) => {
              (item1, [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()
        .padding({ top: 3, bottom: 3 })
        .visibility((text) ?  : )
      Text(text)
        .fontSize(20)
        .fontColor()
        .margin({ top: 3 })
    }.width("12.5%")
  }

  isHanZi(text: string) {
    return (0) >= 0x4e00 && (0) <= 0x9fa5
  }
}

Poetry Reading

@ComponentV2
export struct PoetryDetailPage {
  @Local soundPlayStatus: boolean = false
  ttsEngine:  | null = null

  aboutToDisappear(): void {
    if () {
      ()
      ()
    }
  }

  initEngine(): Promise<void> {
    return new Promise((resolve, reject) => {
      if ( == null) {
        let extraParams: Record<string, Object> = {
          "style": 'interaction-broadcast',
          "locate": 'CN',
          "name": '',
          "isBackStage": true
        }
        let paramsInfo:  = {
          language: 'zh-CN',
          person: 0,
          online: 1,
          extraParams: extraParams
        }
        (paramsInfo).then((value) => {
           = value
          resolve()
        }).catch((err: BusinessError) => {
          ()
          reject()
        })
      } else {
        resolve()
      }
    })
  }
  
  speak() {
    if ( && ()) {
      ()
      return
    }
    ().then(() => {
      let listener:  = {
        onStart: (requestId: string, response: ): void => {
           = true
        },
        onComplete: (requestId: string, response: ): void => {
          if ( == 1) {
             = false
          }
        },
        onStop: (requestId: string, response: ): void => {
           = false
        },
        onError: (requestId: string, errorCode: number, errorMessage: string): void => {
           = false
        }
      }
      ?.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:  = {
        requestId: (),
        extraParams: extraParams
      }
      let speakText =
        `${?.title}[p200]
        ${?.dynasty}[p50]${?.author}[p200]
        ${?.text}`

      ?.speak(speakText, params)
    })
  }
}

The technical design and implementation of this paper are based on the author's work experience, if there is any error, please leave a message to correct, thank you.