# 介绍

浏览器端中文 TTS 控制器，内置流式文本切分与 SSML 转换，支持 iOS/非 iOS 与多供应商接入。

详细配置可参考[参数基本说明](https://www.volcengine.com/docs/6561/79823)。

- ✅ 一行初始化与创建控制器
- ✅ 流式处理与事件订阅
- ✅ SSML 发音规则（<phoneme> 最长匹配）
- ✅ iOS/非 iOS 自动适配

# 安装

```bash
# pnpm
pnpm add @minto-ai/huoshan-tts
```

# 快速开始

```js
import huoshanTts from '@minto-ai/huoshan-tts'

// 配置系统
huoshanTts.config({ ttsRequestBaseUrl: 'wss://audio.workbrain.cn/tts' })

// 创建控制器实例
const tts = huoshanTts.create(
  {
    voice_type: 'zh_female_daimengchuanmei_moon_bigtts',
    text_type: 'plain',
    stream: true,
    provider: '0',
  },
  {
    pronunciationRules: [
      // { content: '重庆', alphabet: 'py', ph: 'chong2 qing4' },
    ],
  },
)

// 订阅事件
tts.on('audioFirstStart', () => {
  console.log('首段音频开始播放')
})

// 启动与推送文本
tts.start()
tts.send('你好，欢迎使用中文 TTS。')
tts.send('这是一段第二句。')
tts.end()

// 结束
tts.finish()
```

# API

## 配置系统

用于设置系统级参数，如 TTS 请求地址。

### config(systemConfig)

> config(\_systemConfig: Partial<SystemConfig>): this

#### 参数

1. `_systemConfig (Partial<SystemConfig))`: 系统配置，如 `ttsRequestBaseUrl: string`

#### 返回值

- `(this)`: 支持链式调用

## 实例方法

核心实例方法，控制 TTS 生命周期与文本推送。

### create(businessParams?, ssmlConfig?)

创建并返回控制器实例，根据设备与供应商自动选择请求与解码管线；用于生命周期管理与文本推送。

> create(\_businessParams?: Partial<BusinessParams>, \_ssmlConfig?: Partial<SsmlConfig>): TtsController

#### 参数

| 参数名                          | 类型                                     | 必填                  | 默认值     | 说明                            |
| ------------------------------- | ---------------------------------------- | --------------------- | ---------- | ------------------------------- | -------------------- | ---------- | ------ | --- | ----- | -------- |
| `businessParams.text_type`      | `'plain'                                 | 'ssml'`               | 否         | `plain`                         | 文本类型             |
| `businessParams.voice_type`     | `string`                                 | 否                    | —          | 音色类型                        |
| `businessParams.speed_ratio`    | `number`                                 | 否                    | `1`        | 语速，约 `[0.2, 3]`             |
| `businessParams.volume_ratio`   | `number`                                 | 否                    | `1`        | 音量，约 `[0.1, 3]`             |
| `businessParams.pitch_ratio`    | `number`                                 | 否                    | `1`        | 音高，约 `[0.1, 3]`             |
| `businessParams.stream`         | `boolean`                                | 否                    | `true`     | 是否流式返回                    |
| `businessParams.language`       | `string`                                 | 否                    | `cn`       | 语言代码                        |
| `businessParams.provider`       | `string`                                 | 否                    | `0`        | 供应商 Id                       |
| `businessParams.cache`          | `boolean`                                | 否                    | `false`    | 是否启用缓存                    |
| `businessParams.encoding`       | `'wav'                                   | 'pcm '                | 'ogg_opus' | 'mp3'`                          | 'pcm'                | 'ogg_opus' | 'mp3'` | 否  | `mp3` | 输出编码 |
| `businessParams.output_format`  | `string`                                 | 否                    | —          | iOS + `provider=100` 时为 `url` |
| `ssmlConfig.pronunciationRules` | `Array<{ content: string; alphabet: 'py' | 'ipa'; ph: string }>` | 否         | `[]`                            | 发音规则（最长匹配） |

#### 返回值

- `(TtsController)`: 控制器实例

### TtsController#start()

进入待机状态，激活处理管线并准备接收文本进行合成。

> start(): TtsController

#### 返回值

- `(TtsController)`: 支持链式调用

### TtsController#send(text)

推送文本或片段，内部进行分段与 SSML 转换后发起合成；支持流式连续调用。

> send(text: string): TtsController

#### 参数

1. `text (string)`: 待转换文本或片段

#### 返回值

- `(TtsController)`: 支持链式调用

### TtsController#end()

停止接收文本输入但不打断当前音频播放；用于输入结束的收尾阶段。

> end(): TtsController

#### 返回值

- `(TtsController)`: 支持链式调用

### TtsController#finish()

停止所有处理器并重置控制器状态，触发 `appFinish` 事件；用于彻底结束并清理。

> finish(): void

#### 返回值

- `(void)`

### TtsController#on(eventName, callback)

订阅控制器公共事件，获取播放开始、错误、结束等通知，支持链式调用。

> on(eventName: PublicCustomEventName, callback: (data?: any) => void): TtsController

#### 参数

1. `eventName (PublicCustomEventName)`: 事件名称
2. `callback ((data?: any) => void)`: 回调函数

#### 返回值

- `(TtsController)`: 支持链式调用

### TtsController#mute()

静音当前音频输出。

> mute(): void

#### 返回值

- `(void)`

### TtsController#unmute()

取消静音，恢复音频输出。

> unmute(): void

#### 返回值

- `(void)`

# 应用事件

| 事件名            | 触发时机                     | 事件说明     |
| ----------------- | ---------------------------- | ------------ |
| `audioFirstStart` | 首段音频开始播放前           | 首次播放提示 |
| `appError`        | 应用发生错误时               | 携带错误信息 |
| `appFinish`       | 调用 `finish()` 或流程结束时 | 应用结束事件 |

## audioFirstStart

触发时机：首段音频片段即将播放前。

作用：用于提示开始播放或进行 UI 预处理。

```js
tts.on('audioFirstStart', () => {
  console.log('首段音频开始播放')
})
```

## appFinish

触发时机：调用 `finish()` 或处理链自然结束。

作用：用于清理资源或提示应用结束。

```js
tts.on('appFinish', () => {
  console.log('应用已结束')
})
```

# 进阶示例

## 流式文本处理

```javascript
import huoshanTts from '@minto-ai/huoshan-tts'

huoshanTts.config()

const ttsInstance = huoshanTts.create({

})

ttsInstance
  .on('appFinish', () => {
    console.log('appFinish')
  })
  .on('audioFirstStart', () => {
    console.log('audioFirstStart')
  })

const zzButton = document.createElement('button')
zzButton.textContent = '终止'
const jxButton = document.createElement('button')
jxButton.textContent = '继续'

let timer = null
zzButton.onclick = () => {
  ttsInstance.finish()
  clearTimeout(timer)
}

jxButton.onclick = () => {
  clearTimeout(timer)

  const arrText = [
    `你要抱`,
    `抱我吗？`,
    `我好`,
    `喜欢你呀！`,
  ]

  let index = 0

  timer = setInterval(() => {
    ttsInstance.send(arrText[index])
    index += 1
    if (index === arrText.length) {
      ttsInstance.end()
      clearInterval(timer)
    }
  }, 100)
}

document.body.appendChild(jxButton)
document.body.appendChild(zzButton)
```

## 多事件组合监听

```js
import huoshanTts from '@minto-ai/huoshan-tts'

const tts = huoshanTts.config({
  ttsRequestBaseUrl: 'wss://audio.workbrain.cn/tts'
}).create({

})
tts
  .on('audioFirstStart', () => console.log('首段开始'))
  .on('appFinish', () => console.log('结束'))
tts.start().send('你好，世界。').end()
setTimeout(
  () => tts.finish(),
  1000
)
```

## SSML 发音规则

```js
import huoshanTts from '@minto-ai/huoshan-tts'

const rules = [{ content: '重庆', alphabet: 'py', ph: 'chong2 qing4' }]
const tts = huoshanTts.config({
  ttsRequestBaseUrl: 'wss://audio.workbrain.cn/tts'
}).create({}, {
  pronunciationRules: rules
})
tts.start().send('我去重庆。').end()
```
