HarmonyOS Core Speech Kit(基础语音服务)完整使用指南

效果

一、概述

Core Speech Kit 是 HarmonyOS 提供的基础语音服务套件,集成了语音类基础 AI 能力。它是 HarmonyOS AI Kit 体系中的重要组成部分,向上为开发者提供声明式 API,向下调用系统内置的离线模型与云端算力,实现文本与语音之间的高效互转。

架构层次:

┌──────────────────────────────────┐
│         应用层 (Application)       │
│        聊天、搜索、输入等场景       │
├──────────────────────────────────┤
│         框架层 (Framework)         │
│     @kit.CoreSpeechKit           │
│  ┌────────────┬────────────┐    │
│  │speechRecognizer│textToSpeech│    │
│  │  (语音识别ASR) │ (语音合成TTS)│    │
│  └────────────┴────────────┘    │
├──────────────────────────────────┤
│      系统服务层 (System Service)   │
│    AI Engine Service             │
│    Audio Service                 │
├──────────────────────────────────┤
│         硬件层 (Hardware)          │
│     麦克风 / 扬声器 / NPU         │
└──────────────────────────────────┘

二、两大核心能力

能力 模块名 功能 适用场景
语音识别 (ASR) speechRecognizer 语音转文字 语音输入、语音搜索、聊天转文字
语音合成 (TTS) textToSpeech 文字转语音 文本朗读、语音播报、有声阅读

2.1 语音识别能力详情

项目 说明
支持语种 中文普通话
模型类型 离线(端侧运行)
短语音模式 ≤ 60 秒
长语音模式 ≤ 8 小时
音频格式 PCM,16kHz,单声道,16位

2.2 语音合成能力详情

项目 说明
支持语种 中文、英文(含中文语境英文)
音色类型 聆小珊女声、劳拉女声(美英)、凌飞哲男声
文本长度 ≤ 10000 字符
离线支持 支持离线播报

三、环境准备

3.1 开发环境要求

  • DevEco Studio 6.1.0 Release 及以上
  • HarmonyOS SDK 6.1.0 Release 及以上
  • 运行设备:华为手机/平板/2in1,HarmonyOS 6.1.0 Release 及以上

3.2 权限配置

语音识别需要麦克风权限:

// entry/src/main/module.json5
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:mic_permission_desc",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "always"
        }
      }
    ]
  }
}

语音合成不需要额外权限(仅播放音频)。

3.3 导入方式

// 语音识别
import { speechRecognizer } from '@kit.CoreSpeechKit';

// 语音合成
import { textToSpeech } from '@kit.CoreSpeechKit';

// 错误码
import { BusinessError } from '@kit.BasicServicesKit';

四、语音识别(ASR)开发步骤

4.1 创建识别引擎

import { speechRecognizer } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';

let asrEngine: speechRecognizer.SpeechRecognitionEngine | undefined = undefined;

const params: speechRecognizer.CreateEngineParams = {
  language: 'zh-CN',
  online: 1,
  extraParams: { 'locate': 'CN', 'recognizerMode': 'short' }
};

speechRecognizer.createEngine(params, (err: BusinessError, engine: speechRecognizer.SpeechRecognitionEngine) => {
  if (err) {
    console.error(`ASR引擎创建失败: ${err.code}`);
    return;
  }
  asrEngine = engine;
  console.info('ASR引擎创建成功');
});

4.2 设置回调并启动识别

// 设置监听
const listener: speechRecognizer.RecognitionListener = {
  onStart: (sessionId: string) => { console.info('识别开始'); },
  onEvent: () => {},
  onResult: (sessionId: string, result: speechRecognizer.SpeechRecognitionResult) => {
    console.info(`识别结果: ${result.result}`);
  },
  onComplete: () => { console.info('识别完成'); },
  onError: (sessionId: string, code: number, msg: string) => {
    console.error(`识别出错: ${code} ${msg}`);
  }
};
asrEngine?.setListener(listener);

// 开始识别
asrEngine?.startListening({
  sessionId: 'session_001',
  audioInfo: { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 }
});

4.3 写入音频数据

import { fileIo as fs } from '@kit.CoreFileKit';

async function writePcmToEngine(filePath: string): Promise<void> {
  const file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
  const buf = new ArrayBuffer(1280);
  const sessionId = 'session_001';
  let offset = 0; // HarmonyOS 中 offset 表示文件读取位置

  while (true) {
    const bytesRead = fs.readSync(file.fd, buf, { offset: offset, length: 1280 });
    if (bytesRead === 0) break;
    asrEngine?.writeAudio(sessionId, new Uint8Array(buf, 0, bytesRead));
    offset += bytesRead;
    await new Promise<void>(r => setTimeout(r, 40));
  }

  asrEngine?.finish(sessionId);
  fs.closeSync(file);
}

五、语音合成(TTS)开发步骤

5.1 创建合成引擎

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

let ttsEngine: textToSpeech.TextToSpeechEngine | undefined = undefined;

const params: textToSpeech.CreateEngineParams = {
  language: 'zh-CN',
  speaker: 'xiaoshan', // 音色:xiaoshan/laura/lingfeizhe
  extraParams: {}
};

textToSpeech.createEngine(params, (err: BusinessError, engine: textToSpeech.TextToSpeechEngine) => {
  if (!err) {
    ttsEngine = engine;
    console.info('TTS引擎创建成功');
  }
});

5.2 设置回调并开始合成

const ttsListener: textToSpeech.CallbackListener = {
  onStart: () => { console.info('合成开始'); },
  onAudioAvailable: (sessionId: string, audioData: textToSpeech.AudioDataInfo) => {
    // 处理音频数据
    console.info(`音频数据就绪: sessionId=${sessionId}`);
  },
  onComplete: (sessionId: string) => { console.info('合成完成'); },
  onError: (sessionId: string, code: number, msg: string) => {
    console.error(`合成错误: ${code} ${msg}`);
  },
  onAudioVolume: (sessionId: string, volume: number, start: number, end: number) => {
    // 音量变化回调
  },
  onMarkReached: (sessionId: string, mark: string) => {
    // 标记到达回调
  }
};
ttsEngine?.setListener(ttsListener);

// 开始合成播报
const speakParams: textToSpeech.SpeakParams = {
  sessionId: 'tts_001',
  text: '你好,欢迎使用鸿蒙语音服务!',
  extraParams: {}
};
ttsEngine?.speak(speakParams);

5.3 控制播报

// 暂停播报
ttsEngine?.pause('tts_001');

// 恢复播报
ttsEngine?.resume('tts_001');

// 停止播报
ttsEngine?.stop('tts_001');

// 销毁引擎
ttsEngine?.shutdown();

5.4 SSML 标记语言增强

Core Speech Kit 支持类 SSML 的控制标签,可精确调节合成效果:

// 多音字纠偏
ttsEngine?.speak({
  sessionId: 'tts_002',
  text: '今天的音乐会将在[=chóng]庆举行',
  extraParams: {}
});

// 数字播报控制
ttsEngine?.speak({
  sessionId: 'tts_003',
  text: '订单号是<say-as interpret-as="cardinal">12345</say-as>',
  extraParams: {}
});

六、完整示例:语音识别 + 语音合成 双功能页面

import { speechRecognizer, textToSpeech } from '@kit.CoreSpeechKit';
import { audio } from '@kit.AudioKit';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct CoreSpeechKitDemo {
  @State asrResult: string = '';
  @State ttsInput: string = '你好,鸿蒙语音合成测试';
  @State status: string = '';
  private asrEngine: speechRecognizer.SpeechRecognitionEngine | undefined = undefined;
  private ttsEngine: textToSpeech.TextToSpeechEngine | undefined = undefined;

  aboutToAppear(): void {
    const ctx = getContext(this) as common.UIAbilityContext;
    abilityAccessCtrl.createAtManager()
      .requestPermissionsFromUser(ctx, ['ohos.permission.MICROPHONE' as Permissions]);
    this.initAsr();
    this.initTts();
  }

  initAsr(): void {
    speechRecognizer.createEngine({
      language: 'zh-CN', online: 1,
      extraParams: { 'locate': 'CN', 'recognizerMode': 'short' }
    }, (err, eng) => {
      if (!err) {
        this.asrEngine = eng;
        this.asrEngine.setListener({
          onStart: () => {},
          onEvent: () => {},
          onResult: (_sid, result) => {
            if (result.result) this.asrResult = result.result;
          },
          onComplete: () => { this.status = '语音识别完成'; },
          onError: (_sid, code) => { this.status = `识别错误: ${code}`; }
        });
      }
    });
  }

  initTts(): void {
    textToSpeech.createEngine({
      language: 'zh-CN', speaker: 'xiaoshan', extraParams: {}
    }, (err, eng) => {
      if (!err) {
        this.ttsEngine = eng;
        this.ttsEngine.setListener({
          onStart: () => { this.status = '正在播报...'; },
          onAudioAvailable: () => {},
          onComplete: () => { this.status = '播报完成'; },
          onError: () => {},
          onAudioVolume: () => {},
          onMarkReached: () => {}
        });
      }
    });
  }

  speakText(): void {
    if (this.ttsInput.trim().length === 0) return;
    this.ttsEngine?.speak({
      sessionId: Date.now().toString(),
      text: this.ttsInput,
      extraParams: {}
    });
  }

  aboutToDisappear(): void {
    this.asrEngine?.shutdown();
    this.ttsEngine?.shutdown();
  }

  build() {
    Column({ space: 16 }) {
      Text('Core Speech Kit 示例')
        .fontSize(22).fontWeight(FontWeight.Bold).margin({ top: 50 })

      // 语音合成区
      Column({ space: 10 }) {
        Text('语音合成 (TTS)').fontSize(16).fontWeight(FontWeight.Medium)
        TextInput({ text: this.ttsInput })
          .width('80%')
          .onChange((v) => { this.ttsInput = v; })
        Button('播报文字')
          .backgroundColor('#4FC08D')
          .onClick(() => this.speakText())
      }
      .padding(16)
      .backgroundColor('#F8F8F8')
      .borderRadius(12)
      .width('90%')

      // 语音识别区
      Column({ space: 10 }) {
        Text('语音识别 (ASR)').fontSize(16).fontWeight(FontWeight.Medium)
        Text(this.asrResult || '识别结果将显示在此')
          .fontColor(this.asrResult ? '#333' : '#CCC')
          .fontSize(15)
      }
      .padding(16)
      .backgroundColor('#F8F8F8')
      .borderRadius(12)
      .width('90%')

      Text(this.status).fontSize(13).fontColor('#999')
    }
    .width('100%').height('100%')
    .justifyContent(FlexAlign.Start)
  }
}

七、约束与限制汇总

能力 约束项 限制说明
语音识别 语种 仅支持中文普通话
语音识别 模型 仅离线模型
语音识别 时长 短语音≤60s,长语音≤8h
语音识别 设备 不支持模拟器
语音合成 语种 中文、英文
语音合成 文本长度 ≤ 10000 字符
语音合成 音色 3 种内置音色
通用 并发 不支持多线程并发调用同一引擎

八、最佳实践

  1. 引擎预热:在页面加载时提前创建引擎,避免用户操作时等待
  2. 资源管理:页面销毁时务必调用 shutdown() 释放引擎
  3. 音频格式:ASR 输入必须是 PCM 格式(16kHz/单声道/16位)
  4. 写入节奏writeAudio 每次 1280 字节,间隔 40ms,模拟实时流速率
  5. 识别结果异步回调onResult 回调是异步触发的,finish() 后需轮询等待结果
  6. 错误处理:始终处理 onError 回调,向用户展示友好提示
  7. 引擎互斥:同一时刻只能有一个应用使用语音识别引擎
  8. fs.readSync offset 语义:HarmonyOS 的 fileIo.readSyncoffset 参数表示文件读取位置(非 Node.js 缓冲区偏移)
  9. 离线优先:Core Speech Kit 采用离线优先策略,地铁/电梯等弱网环境仍可使用

九、总结

Core Speech Kit 提供了 HarmonyOS 平台上的两大语音基础能力:语音识别(ASR)语音合成(TTS)

  • ASR:通过 speechRecognizer 模块,将 PCM 音频转换为文字,适用于聊天转文字、语音搜索等场景
  • TTS:通过 textToSpeech 模块,将文字转换为语音播报,适用于朗读、语音通知等场景

两者结合使用,可以构建完整的语音交互闭环,为应用赋予"听"和"说"的双重能力。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐