HarmonyOS 鸿蒙Next文字转语音TTS功能如何实现?语音合成开发指南

HarmonyOS 鸿蒙Next文字转语音TTS功能如何实现?语音合成开发指南 问题描述

  • HarmonyOS 5.0,DevEco Studio 5.0
  • 需要实现文字转语音功能,将文本朗读出来
  • 不清楚如何调用系统的语音合成API
  • 希望能控制语速、音量等参数

希望了解HarmonyOS文字转语音(TTS)的完整实现方案,包括引擎初始化、参数配置和播放控制

3 回复

解决方案

1. 完整实现代码

import { textToSpeech } from '@kit.CoreSpeechKit'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct TTSPage {
  @State inputText: string = '你好,欢迎使用语音合成功能'
  @State isSpeaking: boolean = false
  @State statusText: string = '准备就绪'
  @State speed: number = 1.0
  @State volume: number = 1.0

  private ttsEngine: textToSpeech.TextToSpeechEngine | null = null

  aboutToAppear(): void {
    this.initTTSEngine()
  }

  aboutToDisappear(): void {
    this.releaseEngine()
  }

  // 初始化TTS引擎
  async initTTSEngine(): Promise<void> {
    const extraParams: Record<string, Object> = {
      "style": "interaction-broadcast",
      "locate": "CN",
      "name": "zh-CN-female-1"
    }
   
    const initParams: textToSpeech.CreateEngineParams = {
      language: 'zh-CN',
      person: 0,  // 0: 女声, 1: 男声
      online: 1,  // 1: 在线, 0: 离线
      extraParams: extraParams
    }
   
    try {
      this.ttsEngine = await textToSpeech.createEngine(initParams)
      this.setListener()
      this.statusText = '引擎初始化成功'
    } catch (err) {
      const error = err as BusinessError
      console.error(`TTS引擎初始化失败: ${error.code} - ${error.message}`)
      this.statusText = '初始化失败'
    }
  }

  // 设置播放回调
  setListener(): void {
    if (!this.ttsEngine) return
   
    const listener: textToSpeech.SpeakListener = {
      onStart: (requestId: string, response: textToSpeech.StartResponse) => {
        this.isSpeaking = true
        this.statusText = '正在播放...'
      },
      onProgress: (requestId: string, progress: number, info: textToSpeech.ProgressInfo) => {
        // 播放进度回调
      },
      onFinish: (requestId: string, response: textToSpeech.FinishResponse) => {
        this.isSpeaking = false
        this.statusText = '播放完成'
      },
      onStop: (requestId: string, response: textToSpeech.StopResponse) => {
        this.isSpeaking = false
        this.statusText = '已停止'
      },
      onError: (requestId: string, errorCode: number, errorMessage: string) => {
        this.isSpeaking = false
        this.statusText = `错误: ${errorMessage}`
        console.error(`TTS错误: ${errorCode} - ${errorMessage}`)
      }
    }
   
    this.ttsEngine.setListener(listener)
  }

  // 开始播放
  startSpeak(): void {
    if (!this.ttsEngine || this.isSpeaking || !this.inputText) return
   
    const speakParams: textToSpeech.SpeakParams = {
      requestId: Date.now().toString(),
      extraParams: {
        "speed": this.speed,
        "volume": this.volume,
        "pitch": 1.0,
        "languageContext": "zh-CN",
        "audioType": "pcm"
      }
    }
   
    try {
      this.ttsEngine.speak(this.inputText, speakParams)
    } catch (err) {
      console.error('播放失败:', err)
    }
  }

  // 停止播放
  stopSpeak(): void {
    if (!this.ttsEngine || !this.isSpeaking) return
   
    try {
      this.ttsEngine.stop()
    } catch (err) {
      console.error('停止失败:', err)
    }
  }

  // 释放引擎
  releaseEngine(): void {
    if (this.ttsEngine) {
      try {
        this.ttsEngine.shutdown()
        this.ttsEngine = null
      } catch (err) {
        console.error('释放引擎失败:', err)
      }
    }
  }

  build() {
    Column({ space: 16 }) {
      // 状态显示
      Text(this.statusText)
        .fontSize(14)
        .fontColor($r('app.color.text_secondary'))
     
      // 文本输入
      TextArea({ text: this.inputText })
        .onChange((value: string) => {
          this.inputText = value
        })
        .height(150)
        .backgroundColor($r('app.color.surface'))
        .borderRadius(12)
        .padding(12)
     
      // 语速控制
      Row() {
        Text('语速')
          .fontSize(14)
          .fontColor($r('app.color.text_primary'))
          .width(60)
        Slider({
          value: this.speed,
          min: 0.5,
          max: 2.0,
          step: 0.1
        })
          .onChange((value: number) => {
            this.speed = value
          })
          .layoutWeight(1)
        Text(this.speed.toFixed(1))
          .fontSize(14)
          .width(40)
      }
      .width('100%')
     
      // 音量控制
      Row() {
        Text('音量')
          .fontSize(14)
          .fontColor($r('app.color.text_primary'))
          .width(60)
        Slider({
          value: this.volume,
          min: 0.1,
          max: 1.0,
          step: 0.1
        })
          .onChange((value: number) => {
            this.volume = value
          })
          .layoutWeight(1)
        Text(this.volume.toFixed(1))
          .fontSize(14)
          .width(40)
      }
      .width('100%')
     
      // 控制按钮
      Row({ space: 16 }) {
        Button(this.isSpeaking ? '停止' : '播放')
          .width(120)
          .height(44)
          .backgroundColor(this.isSpeaking ? '#ef4444' : '#36e27b')
          .onClick(() => {
            if (this.isSpeaking) {
              this.stopSpeak()
            } else {
              this.startSpeak()
            }
          })
      }
    }
    .width('100%')
    .height('100%')
    .padding(16)
    .backgroundColor($r('app.color.background'))
  }
}

2. 关键参数说明

参数 说明 取值范围
language 语言 ‘zh-CN’, ‘en-US’
person 发音人 0: 女声, 1: 男声
online 模式 1: 在线, 0: 离线
speed 语速 0.5 - 2.0
volume 音量 0.1 - 1.0
pitch 音调 0.5 - 2.0

3. 切换发音人

async switchVoice(person: number): Promise<void> {
  this.releaseEngine()

  const initParams: textToSpeech.CreateEngineParams = {
    language: 'zh-CN',
    person: person,  // 0: 女声, 1: 男声
    online: 1,
    extraParams: {
      "style": "interaction-broadcast",
      "locate": "CN"
    }
  }

  this.ttsEngine = await textToSpeech.createEngine(initParams)
  this.setListener()
}

更多关于HarmonyOS 鸿蒙Next文字转语音TTS功能如何实现?语音合成开发指南的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next的TTS功能通过@ohos.tts模块实现。主要步骤:1. 导入模块import tts from '@ohos.tts';2. 创建TTS实例tts.createTts();3. 调用speak()方法合成语音。支持设置语速、音调等参数。需在module.json5中声明ohos.permission.INTERNET权限。

在HarmonyOS Next中,文字转语音(TTS)功能主要通过@ohos.tts(语音合成)模块实现。以下是核心实现步骤和代码示例。

1. 权限申请与模块导入

首先,在module.json5文件中申请必要权限并导入模块。

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET" // 在线引擎可能需要网络
      }
    ],
    "importedModules": [
      "@ohos.tts"
    ]
  }
}

在代码中导入:

import tts from '@ohos.tts';

2. 初始化TTS引擎

创建并配置TTS引擎实例,支持设置语速、音量、音高等参数。

// 创建TTS引擎实例
let ttsEngine: tts.TtsEngine;
try {
  ttsEngine = await tts.createTtsEngine({
    voice: 'zh-CN-st-1', // 语音模型,例如中文女声
    speed: 1.0,          // 语速,范围0.5-2.0
    volume: 0.8,         // 音量,范围0.0-1.0
    pitch: 1.0           // 音高,范围0.5-2.0
  });
} catch (err) {
  console.error('TTS引擎初始化失败:', err.code, err.message);
}

3. 语音合成与播放

调用speak方法合成并播放语音,支持同步和异步控制。

// 基本播放
ttsEngine.speak('你好,鸿蒙世界!').then(() => {
  console.info('播放开始');
}).catch((err: BusinessError) => {
  console.error('播放失败:', err.code, err.message);
});

// 带参数播放(覆盖初始化设置)
ttsEngine.speak('正在调整参数', {
  speed: 1.5,
  volume: 1.0
});

4. 播放控制

提供暂停、恢复、停止等精细控制。

// 暂停播放
ttsEngine.pause();

// 恢复播放
ttsEngine.resume();

// 停止播放
ttsEngine.stop();

// 释放引擎资源(退出时调用)
ttsEngine.release();

5. 高级功能

  • 队列播放:通过speak连续调用,自动排队播放。
  • 状态监听:使用on('playStatusChange')监听播放状态。
ttsEngine.on('playStatusChange', (state: tts.PlayStatus) => {
  switch (state) {
    case tts.PlayStatus.PLAYING:
      console.info('开始播放');
      break;
    case tts.PlayStatus.PAUSED:
      console.info('已暂停');
      break;
    case tts.PlayStatus.STOPPED:
      console.info('已停止');
      break;
  }
});

6. 参数配置说明

  • 语音模型:系统预置zh-CN-st-1(中文女声)、en-US-st-1(英文男声)等,支持在线扩展。
  • 语速/音量/音高:数值为相对值,建议在UI中提供滑块控件供用户调节。

注意事项

  • 在线语音合成需网络权限,离线合成无需网络但需预下载模型。
  • 播放前建议检查ttsEngine状态,避免空指针操作。
  • 后台播放需申请ohos.permission.USE_BACKGROUND_TTS权限。

以上方案基于HarmonyOS Next的Stage模型和API 12,实际开发时请参考官方文档确保API兼容性。

回到顶部