> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 客户端模式 - 预设 - VOICEVOX for Laravel

> 介绍在 VOICEVOX for Laravel 的客户端模式下操作官方引擎的预设，保存并复用语音合成参数的方法。

使用预设功能，你可以将常用的语音合成参数组合保存到官方 VOICEVOX 引擎中并复用。在客户端模式下，Laravel 侧不会保存预设，而是使用所连接的官方引擎所管理的预设 API。

## 概览

客户端模式的预设通过 `Voicevox` Facade 操作。内部会向官方 VOICEVOX 引擎的 `/presets`、`/add_preset`、`/update_preset`、`/delete_preset`、`/audio_query_from_preset` 发送 HTTP 请求。

官方引擎的预设按 OS 保存在用户目录下的 `presets.yaml` 中。VOICEVOX 应用（产品版）macOS 构建版通常保存在以下位置。

```text theme={null}
~/Library/Application Support/voicevox-engine/presets.yaml
```

通过 Docker 启动官方引擎时，也保存在容器内的用户目录中。只要一直使用同一个容器，即使重启数据也会保留。但如果像 `docker run --rm` 那样每次都创建临时容器，容器结束时预设会丢失。若需要可靠地持久化预设，请使用 Docker volume 挂载容器内的用户目录。

它与原生模式的 `storage/voicevox/presets.json` 是分开管理的。Laravel 侧的 `config('voicevox.core.presets')` 不会在客户端模式下使用。

## 前置准备

启动官方 VOICEVOX 引擎。

```shell theme={null}
docker pull voicevox/voicevox_engine:cpu-latest
docker run --rm -p '127.0.0.1:50021:50021' voicevox/voicevox_engine:cpu-latest
```

可通过 `VOICEVOX_URL` 修改连接地址。

```env theme={null}
VOICEVOX_URL=http://127.0.0.1:50021
```

## 预设的结构

客户端模式下收发的预设是与官方引擎 API 结构一致的数组。

```php theme={null}
[
    'id' => 1,                // 预设 ID（整数）
    'name' => 'ゆっくり',      // 预设名称
    'speaker_uuid' => 'uuid', // 说话人 UUID（字符串）
    'style_id' => 1,          // Style ID（整数）
    'speedScale' => 0.8,      // 语速
    'pitchScale' => 0.0,      // 音高
    'intonationScale' => 1.0, // 抑扬
    'volumeScale' => 1.0,     // 音量
    'prePhonemeLength' => 0.1, // 起始静音
    'postPhonemeLength' => 0.1, // 结束静音
]
```

## 基本使用

### 创建预设

通过 `Voicevox::addPreset()` 创建预设。在官方引擎中，将 `id` 指定为 `0` 会自动分配一个未使用的 ID。

```php theme={null}
use Revolution\Voicevox\Voicevox;

$id = Voicevox::addPreset([
    'id' => 0,
    'name' => 'ゆっくり丁寧',
    'speaker_uuid' => '7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff',
    'style_id' => 1,
    'speedScale' => 0.8,
    'pitchScale' => 0.0,
    'intonationScale' => 1.2,
    'volumeScale' => 1.0,
    'prePhonemeLength' => 0.1,
    'postPhonemeLength' => 0.1,
]);

echo $id; // 例如：1
```

### 获取所有预设

```php theme={null}
use Revolution\Voicevox\Voicevox;

$presets = Voicevox::presets();

/*
[
    [
        "id" => 1,
        "name" => "ゆっくり丁寧",
        "speaker_uuid" => "7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff",
        "style_id" => 1,
        "speedScale" => 0.8,
        ...
    ],
    ...
]
*/
```

### 更新预设

```php theme={null}
use Revolution\Voicevox\Voicevox;

$id = Voicevox::updatePreset([
    'id' => 1,
    'name' => 'ゆっくりはっきり',
    'speaker_uuid' => '7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff',
    'style_id' => 1,
    'speedScale' => 0.7,
    'pitchScale' => 0.0,
    'intonationScale' => 1.5,
    'volumeScale' => 1.0,
    'prePhonemeLength' => 0.1,
    'postPhonemeLength' => 0.1,
]);
```

### 删除预设

```php theme={null}
use Revolution\Voicevox\Voicevox;

Voicevox::deletePreset(1);
```

## 使用预设进行语音合成

### talkFromPreset()

`Voicevox::talkFromPreset()` 使用官方引擎的 `/audio_query_from_preset`，创建已应用预设的 `TalkAudioQuery`。

```php theme={null}
use Revolution\Voicevox\Voicevox;

$response = Voicevox::talkFromPreset('プリセットを使うのだ', presetId: 1)
    ->generate(id: 1);

$response->storeAs('client', 'preset-talk.wav');
```

### audioQueryFromPreset()

如果只想获取语音合成前的 audio query 数组，可以使用 `audioQueryFromPreset()`。

```php theme={null}
use Revolution\Voicevox\Voicevox;

$audioQuery = Voicevox::audioQueryFromPreset(
    text: 'プリセットのクエリだけ作るのだ',
    presetId: 1,
);

$audioQuery['speedScale'] = 1.1;
```

### 使用 tap() 追加调整

由预设创建的 `TalkAudioQuery` 也可以像普通的 `Voicevox::talk()` 一样通过 `tap()` 进行调整。

```php theme={null}
use Revolution\Voicevox\Client\TalkAudioQuery;
use Revolution\Voicevox\Voicevox;

$response = Voicevox::talkFromPreset('少し速く読むのだ', presetId: 1)
    ->tap(function (TalkAudioQuery $talk) {
        $talk->audioQuery['speedScale'] = 1.2;
    })
    ->generate(id: 1);
```

## 与引擎 API 的对应关系

`Voicevox` Facade 的各方法对应官方引擎的 API。

| Laravel                            | 官方引擎 API                                            |
| ---------------------------------- | --------------------------------------------------- |
| `Voicevox::presets()`              | `GET /presets`                                      |
| `Voicevox::addPreset()`            | `POST /add_preset`                                  |
| `Voicevox::updatePreset()`         | `POST /update_preset`                               |
| `Voicevox::deletePreset()`         | `POST /delete_preset`                               |
| `Voicevox::audioQueryFromPreset()` | `POST /audio_query_from_preset`                     |
| `Voicevox::talkFromPreset()`       | `POST /audio_query_from_preset` + `POST /synthesis` |

## 与原生模式的区别

| 项目             | 客户端模式                                                        | 原生模式                            |
| -------------- | ------------------------------------------------------------ | ------------------------------- |
| 使用方式           | `Voicevox` Facade                                            | `preset()` / `talk()` helper    |
| 保存格式           | 官方引擎的 `presets.yaml`                                         | Laravel 的 `presets.json`        |
| macOS 示例       | `~/Library/Application Support/voicevox-engine/presets.yaml` | `storage/voicevox/presets.json` |
| audio query 生成 | 官方引擎的 `/audio_query_from_preset`                             | Laravel 侧的原生实现                  |
| 引擎进程           | 需要                                                           | 不需要（需要 FFI）                     |

## 实用示例

### 用于旁白

```php theme={null}
use Revolution\Voicevox\Voicevox;

Voicevox::addPreset([
    'id' => 0,
    'name' => 'ナレーション',
    'speaker_uuid' => '7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff',
    'style_id' => 1,
    'speedScale' => 1.0,
    'pitchScale' => -0.05,
    'intonationScale' => 0.8,
    'volumeScale' => 1.0,
    'prePhonemeLength' => 0.15,
    'postPhonemeLength' => 0.15,
]);
```

### 用于快速讲话

```php theme={null}
Voicevox::addPreset([
    'id' => 0,
    'name' => '早口',
    'speaker_uuid' => '388f246b-8c41-4ac1-8e2d-5d79f3ff56d9',
    'style_id' => 3,
    'speedScale' => 1.5,
    'pitchScale' => 0.05,
    'intonationScale' => 1.3,
    'volumeScale' => 1.0,
    'prePhonemeLength' => 0.05,
    'postPhonemeLength' => 0.05,
]);
```

## 参数详情

* `speedScale`：0.5 ～ 2.0（语速）
* `pitchScale`：-0.15 ～ 0.15（音高）
* `intonationScale`：0.0 ～ 2.0（抑扬）
* `volumeScale`：0.0 ～ 2.0（音量）
* `prePhonemeLength`：0.0 ～ 1.5（起始静音・秒）
* `postPhonemeLength`：0.0 ～ 1.5（结束静音・秒）

## 注意事项

<Warning>
  客户端模式下会更新官方引擎侧的 `presets.yaml`。不会保存到 Laravel 项目的 `storage`。
</Warning>

* 使用 `docker run --rm` 等每次创建临时容器时，容器结束时预设会丢失。
* 请同时包含 `speaker_uuid` 和 `style_id`。
* 对 `talkFromPreset()` 创建的 query 调用 `generate(id:)` 时，通常应指定与预设的 `style_id` 相同的 ID。

## 故障排查

### 无法获取预设

1. 请确认官方 VOICEVOX 引擎已启动。
2. 请确认 `VOICEVOX_URL` 指向正确的连接地址。
3. 请确认没有在 Docker 中重新启动到另一个容器。

### 不清楚预设文件的位置

在 macOS 构建版中请确认以下位置。

```text theme={null}
~/Library/Application Support/voicevox-engine/presets.yaml
```

在 Docker 中会保存在官方引擎的用户目录（容器内）。如果需要持久化，请通过 Docker volume 挂载容器内的用户目录。

### 不清楚 speaker\_uuid

可以从说话人列表中获取 UUID。

```php theme={null}
use Revolution\Voicevox\Voicevox;

$speakers = Voicevox::speakers();

foreach ($speakers as $speaker) {
    echo $speaker['name'].': '.$speaker['speaker_uuid'].PHP_EOL;
}
```


## Related topics

- [客户端模式 - 用户词典 - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/client-user-dict.md)
- [客户端模式：Song（歌声合成） - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/client-song.md)
- [客户端模式：Talk（文本语音合成） - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/client-talk.md)
- [原生模式：Song（歌声合成） - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/native-song.md)
- [原生模式：Talk（文本语音合成） - VOICEVOX for Laravel](/zh/packages/laravel-voicevox/native-talk.md)
