tts-plugin-edgetts 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tts_plugin_edgetts-0.1.0/.gitignore +37 -0
- tts_plugin_edgetts-0.1.0/AGENTS.md +27 -0
- tts_plugin_edgetts-0.1.0/LICENSE +21 -0
- tts_plugin_edgetts-0.1.0/PKG-INFO +157 -0
- tts_plugin_edgetts-0.1.0/README.md +129 -0
- tts_plugin_edgetts-0.1.0/pyproject.toml +53 -0
- tts_plugin_edgetts-0.1.0/reports/edgetts_01_design.md +97 -0
- tts_plugin_edgetts-0.1.0/reports/edgetts_02_worklog.md +135 -0
- tts_plugin_edgetts-0.1.0/tests/test_connector.py +249 -0
- tts_plugin_edgetts-0.1.0/tests/test_factory.py +99 -0
- tts_plugin_edgetts-0.1.0/tts_plugin_edgetts/__init__.py +3 -0
- tts_plugin_edgetts-0.1.0/tts_plugin_edgetts/connector.py +86 -0
- tts_plugin_edgetts-0.1.0/uv.lock +1653 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environment
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
ENV/
|
|
10
|
+
|
|
11
|
+
# IDE
|
|
12
|
+
.idea/
|
|
13
|
+
.vscode/
|
|
14
|
+
|
|
15
|
+
# Build
|
|
16
|
+
build/
|
|
17
|
+
dist/
|
|
18
|
+
|
|
19
|
+
# Cache
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
|
|
24
|
+
# Logs
|
|
25
|
+
*.log
|
|
26
|
+
|
|
27
|
+
# Coverage
|
|
28
|
+
.coverage
|
|
29
|
+
|
|
30
|
+
# Generated agent notes
|
|
31
|
+
GEMINI.md
|
|
32
|
+
|
|
33
|
+
# Environment variables
|
|
34
|
+
.env
|
|
35
|
+
.env.local
|
|
36
|
+
|
|
37
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# tts-plugin-edgetts
|
|
2
|
+
|
|
3
|
+
**Plugin for Microsoft Edge TTS (edge-tts backend)**
|
|
4
|
+
|
|
5
|
+
## KEY FILES
|
|
6
|
+
| File | Role |
|
|
7
|
+
|------|------|
|
|
8
|
+
| `tts_plugin_edgetts/connector.py` | EdgeTTSConnector implementation |
|
|
9
|
+
|
|
10
|
+
## ENTRY POINT
|
|
11
|
+
```python
|
|
12
|
+
# pyproject.toml
|
|
13
|
+
[project.entry-points."tts_bridge.connectors"]
|
|
14
|
+
edgetts = "tts_plugin_edgetts.connector:EdgeTTSConnector"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## USAGE
|
|
18
|
+
```bash
|
|
19
|
+
tts-plugin-bridge synthesize "こんにちは" -e edgetts
|
|
20
|
+
tts-plugin-bridge synthesize "Hello" -e edgetts --pitch +5Hz
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## CONVENTIONS
|
|
24
|
+
- Depends on: `tts-plugin-bridge` (core), `edge-tts` (TTS engine)
|
|
25
|
+
- Uses `edge_tts.Communicate` async API
|
|
26
|
+
- Inherits `TTSConnector` ABC
|
|
27
|
+
- Output format: MP3 (24kHz, 48kbps, mono)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vox4ai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tts-plugin-edgetts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Microsoft Edge TTS 向け TTS Plugin (edge-tts backend)
|
|
5
|
+
Project-URL: Homepage, https://github.com/vox4ai/tts-plugin-edgetts
|
|
6
|
+
Project-URL: Repository, https://github.com/vox4ai/tts-plugin-edgetts
|
|
7
|
+
Project-URL: Issues, https://github.com/vox4ai/tts-plugin-edgetts/issues
|
|
8
|
+
Author-email: utenadev <utena.cross+pypi@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: edge,edgetts,microsoft,speech,synthesis,tts,tts-plugin,voice
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: edge-tts>=7.0
|
|
26
|
+
Requires-Dist: tts-plugin-bridge
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# tts-plugin-edgetts
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="https://via.placeholder.com/1200x400/1a1a1a/ffffff?text=tts-plugin-edgetts" alt="tts-plugin-edgetts Banner" width="1200">
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://img.shields.io/badge/pypi-latest-blue.svg" alt="PyPI version">
|
|
37
|
+
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
|
|
38
|
+
<img src="https://img.shields.io/badge/python-3.10%2B-yellow.svg" alt="Python Version">
|
|
39
|
+
<img src="https://img.shields.io/badge/maintained%3F-yes-brightgreen.svg" alt="Maintained">
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<p align="center">
|
|
43
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts">Website</a> •
|
|
44
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts/issues">Report Bug</a> •
|
|
45
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts/contributing">Contributing</a>
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🚀 Overview
|
|
51
|
+
|
|
52
|
+
[edge-tts](https://github.com/rany2/edge-tts) (Microsoft Edge TTS) を `tts-plugin-bridge` で利用するためのプラグインです。
|
|
53
|
+
APIキー不要で多言語対応のTTSが利用できます。
|
|
54
|
+
|
|
55
|
+
## 📦 インストール
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv add tts-plugin-bridge tts-plugin-edgetts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## ⚙️ 前提条件
|
|
62
|
+
|
|
63
|
+
- インターネット接続 (Microsoft Edge TTSサービスにアクセス)
|
|
64
|
+
- ローカルサーバー不要
|
|
65
|
+
- 再生には [ffplay](https://ffmpeg.org/ffplay.html) または `paplay` / `aplay` がPATHに存在すること
|
|
66
|
+
- ffplay がある場合: ストリーミング再生(受信しながら即時再生)
|
|
67
|
+
- ffplay がない場合: 全取得後に paplay / aplay で再生
|
|
68
|
+
|
|
69
|
+
## 🛠 Usage
|
|
70
|
+
|
|
71
|
+
### 🧩 Python API
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from tts_plugin_bridge import TTSSkill
|
|
75
|
+
|
|
76
|
+
async with TTSSkill(default_engine="edgetts") as skill:
|
|
77
|
+
# save / synthesize — ファイル保存やBase64取得用
|
|
78
|
+
res = await skill.save(
|
|
79
|
+
text="こんにちは、エッジティーティーエスのテストです。",
|
|
80
|
+
speed=1.2,
|
|
81
|
+
model="ja-JP-KeitaNeural",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# say / play — 直接再生(ffplayストリーミング → paplay/aplay)
|
|
85
|
+
res = await skill.say(
|
|
86
|
+
text="ストリーミングで即時再生します。",
|
|
87
|
+
speed=1.0,
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 🎤 CLI(vox4ai 推奨)
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# 直接再生(自動ストリーミング)
|
|
95
|
+
vox4ai say "こんにちは" -e edgetts
|
|
96
|
+
|
|
97
|
+
# 男性声で再生
|
|
98
|
+
vox4ai say "こんにちは" -e edgetts --model ja-JP-KeitaNeural
|
|
99
|
+
|
|
100
|
+
# ファイル保存(MP3)
|
|
101
|
+
vox4ai save "こんにちは" -e edgetts -o output.mp3
|
|
102
|
+
|
|
103
|
+
# 環境診断
|
|
104
|
+
vox4ai --doctor
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### ⌨️ CLI(tts-plugin-bridge 後方互換)
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
tts-plugin-bridge synthesize "こんにちは" -e edgetts -o output.mp3
|
|
111
|
+
tts-plugin-bridge play "こんにちは" -e edgetts
|
|
112
|
+
tts-plugin-bridge play "こんにちは" -e edgetts --model ja-JP-KeitaNeural
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 🔧 サポートパラメータ
|
|
116
|
+
|
|
117
|
+
| パラメータ | 型 | 説明 |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `speed` | float | 話速 (1.0=標準, >1.0=速い) → edge-tts `rate` に自動変換 |
|
|
120
|
+
| `volume` | float | 音量倍率 → edge-tts `volume` に自動変換 |
|
|
121
|
+
| `model` | str | 音声名 (例: `ja-JP-KeitaNeural`) → edge-tts `voice` にマッピング |
|
|
122
|
+
| `extra.pitch` | str | ピッチ (例: `+5Hz`, `-10Hz`) |
|
|
123
|
+
| `extra.rate` | str | 話速の直接指定 (例: `+50%`, `-20%`)。speed変換より優先 |
|
|
124
|
+
| `extra.volume` | str | 音量の直接指定 (例: `+100%`)。volume変換より優先 |
|
|
125
|
+
| `extra.voice` | str | 音声名の直接指定。modelより優先 |
|
|
126
|
+
| `extra.proxy` | str | プロキシURL |
|
|
127
|
+
|
|
128
|
+
### 🗣️ 主な音声一覧
|
|
129
|
+
|
|
130
|
+
| 音声名 | 性別 | 言語 |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `ja-JP-NanamiNeural` | 女性 | 日本語 (デフォルト) |
|
|
133
|
+
| `ja-JP-KeitaNeural` | 男性 | 日本語 |
|
|
134
|
+
| `en-US-EmmaMultilingualNeural` | 女性 | 英語 (多言語対応) |
|
|
135
|
+
| `en-US-AndrewNeural` | 男性 | 英語 |
|
|
136
|
+
|
|
137
|
+
全音声一覧: `uv run edge-tts --list-voices`
|
|
138
|
+
|
|
139
|
+
### 📁 出力フォーマット
|
|
140
|
+
|
|
141
|
+
MP3 (24kHz, 48kbps, mono)
|
|
142
|
+
|
|
143
|
+
## 🔍 検証環境
|
|
144
|
+
|
|
145
|
+
- **OS**: Windows 11 + WSL2 (Ubuntu)
|
|
146
|
+
- **確認日**: 2026-05-09
|
|
147
|
+
- **依存**: edge-tts v7.2.8, bridge / vox4ai CLI
|
|
148
|
+
- **確認内容**:
|
|
149
|
+
- `vox4ai say` によるストリーミング再生(ffplay 経由)
|
|
150
|
+
- `vox4ai save` による MP3 ファイル保存
|
|
151
|
+
- `vox4ai --doctor` 環境診断
|
|
152
|
+
- `tts-plugin-bridge` CLI 後方互換維持
|
|
153
|
+
- 全ユニットテスト 22件 パス
|
|
154
|
+
|
|
155
|
+
## 📜 ライセンス
|
|
156
|
+
|
|
157
|
+
MIT License
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# tts-plugin-edgetts
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://via.placeholder.com/1200x400/1a1a1a/ffffff?text=tts-plugin-edgetts" alt="tts-plugin-edgetts Banner" width="1200">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="https://img.shields.io/badge/pypi-latest-blue.svg" alt="PyPI version">
|
|
9
|
+
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
|
|
10
|
+
<img src="https://img.shields.io/badge/python-3.10%2B-yellow.svg" alt="Python Version">
|
|
11
|
+
<img src="https://img.shields.io/badge/maintained%3F-yes-brightgreen.svg" alt="Maintained">
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts">Website</a> •
|
|
16
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts/issues">Report Bug</a> •
|
|
17
|
+
<a href="https://github.com/vox4ai/tts-plugin-edgetts/contributing">Contributing</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Overview
|
|
23
|
+
|
|
24
|
+
[edge-tts](https://github.com/rany2/edge-tts) (Microsoft Edge TTS) を `tts-plugin-bridge` で利用するためのプラグインです。
|
|
25
|
+
APIキー不要で多言語対応のTTSが利用できます。
|
|
26
|
+
|
|
27
|
+
## 📦 インストール
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv add tts-plugin-bridge tts-plugin-edgetts
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ⚙️ 前提条件
|
|
34
|
+
|
|
35
|
+
- インターネット接続 (Microsoft Edge TTSサービスにアクセス)
|
|
36
|
+
- ローカルサーバー不要
|
|
37
|
+
- 再生には [ffplay](https://ffmpeg.org/ffplay.html) または `paplay` / `aplay` がPATHに存在すること
|
|
38
|
+
- ffplay がある場合: ストリーミング再生(受信しながら即時再生)
|
|
39
|
+
- ffplay がない場合: 全取得後に paplay / aplay で再生
|
|
40
|
+
|
|
41
|
+
## 🛠 Usage
|
|
42
|
+
|
|
43
|
+
### 🧩 Python API
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from tts_plugin_bridge import TTSSkill
|
|
47
|
+
|
|
48
|
+
async with TTSSkill(default_engine="edgetts") as skill:
|
|
49
|
+
# save / synthesize — ファイル保存やBase64取得用
|
|
50
|
+
res = await skill.save(
|
|
51
|
+
text="こんにちは、エッジティーティーエスのテストです。",
|
|
52
|
+
speed=1.2,
|
|
53
|
+
model="ja-JP-KeitaNeural",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# say / play — 直接再生(ffplayストリーミング → paplay/aplay)
|
|
57
|
+
res = await skill.say(
|
|
58
|
+
text="ストリーミングで即時再生します。",
|
|
59
|
+
speed=1.0,
|
|
60
|
+
)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 🎤 CLI(vox4ai 推奨)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# 直接再生(自動ストリーミング)
|
|
67
|
+
vox4ai say "こんにちは" -e edgetts
|
|
68
|
+
|
|
69
|
+
# 男性声で再生
|
|
70
|
+
vox4ai say "こんにちは" -e edgetts --model ja-JP-KeitaNeural
|
|
71
|
+
|
|
72
|
+
# ファイル保存(MP3)
|
|
73
|
+
vox4ai save "こんにちは" -e edgetts -o output.mp3
|
|
74
|
+
|
|
75
|
+
# 環境診断
|
|
76
|
+
vox4ai --doctor
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### ⌨️ CLI(tts-plugin-bridge 後方互換)
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
tts-plugin-bridge synthesize "こんにちは" -e edgetts -o output.mp3
|
|
83
|
+
tts-plugin-bridge play "こんにちは" -e edgetts
|
|
84
|
+
tts-plugin-bridge play "こんにちは" -e edgetts --model ja-JP-KeitaNeural
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 🔧 サポートパラメータ
|
|
88
|
+
|
|
89
|
+
| パラメータ | 型 | 説明 |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `speed` | float | 話速 (1.0=標準, >1.0=速い) → edge-tts `rate` に自動変換 |
|
|
92
|
+
| `volume` | float | 音量倍率 → edge-tts `volume` に自動変換 |
|
|
93
|
+
| `model` | str | 音声名 (例: `ja-JP-KeitaNeural`) → edge-tts `voice` にマッピング |
|
|
94
|
+
| `extra.pitch` | str | ピッチ (例: `+5Hz`, `-10Hz`) |
|
|
95
|
+
| `extra.rate` | str | 話速の直接指定 (例: `+50%`, `-20%`)。speed変換より優先 |
|
|
96
|
+
| `extra.volume` | str | 音量の直接指定 (例: `+100%`)。volume変換より優先 |
|
|
97
|
+
| `extra.voice` | str | 音声名の直接指定。modelより優先 |
|
|
98
|
+
| `extra.proxy` | str | プロキシURL |
|
|
99
|
+
|
|
100
|
+
### 🗣️ 主な音声一覧
|
|
101
|
+
|
|
102
|
+
| 音声名 | 性別 | 言語 |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `ja-JP-NanamiNeural` | 女性 | 日本語 (デフォルト) |
|
|
105
|
+
| `ja-JP-KeitaNeural` | 男性 | 日本語 |
|
|
106
|
+
| `en-US-EmmaMultilingualNeural` | 女性 | 英語 (多言語対応) |
|
|
107
|
+
| `en-US-AndrewNeural` | 男性 | 英語 |
|
|
108
|
+
|
|
109
|
+
全音声一覧: `uv run edge-tts --list-voices`
|
|
110
|
+
|
|
111
|
+
### 📁 出力フォーマット
|
|
112
|
+
|
|
113
|
+
MP3 (24kHz, 48kbps, mono)
|
|
114
|
+
|
|
115
|
+
## 🔍 検証環境
|
|
116
|
+
|
|
117
|
+
- **OS**: Windows 11 + WSL2 (Ubuntu)
|
|
118
|
+
- **確認日**: 2026-05-09
|
|
119
|
+
- **依存**: edge-tts v7.2.8, bridge / vox4ai CLI
|
|
120
|
+
- **確認内容**:
|
|
121
|
+
- `vox4ai say` によるストリーミング再生(ffplay 経由)
|
|
122
|
+
- `vox4ai save` による MP3 ファイル保存
|
|
123
|
+
- `vox4ai --doctor` 環境診断
|
|
124
|
+
- `tts-plugin-bridge` CLI 後方互換維持
|
|
125
|
+
- 全ユニットテスト 22件 パス
|
|
126
|
+
|
|
127
|
+
## 📜 ライセンス
|
|
128
|
+
|
|
129
|
+
MIT License
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tts-plugin-edgetts"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Microsoft Edge TTS 向け TTS Plugin (edge-tts backend)"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"tts-plugin-bridge",
|
|
12
|
+
"edge-tts>=7.0",
|
|
13
|
+
]
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
license = {text = "MIT"}
|
|
16
|
+
authors = [
|
|
17
|
+
{name = "utenadev", email = "utena.cross+pypi@gmail.com"},
|
|
18
|
+
]
|
|
19
|
+
keywords = ["tts", "tts-plugin", "edgetts", "microsoft", "edge", "voice", "speech", "synthesis"]
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Development Status :: 4 - Beta",
|
|
22
|
+
"Environment :: Console",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"License :: OSI Approved :: MIT License",
|
|
25
|
+
"Operating System :: OS Independent",
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"Programming Language :: Python :: 3.10",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13",
|
|
31
|
+
"Topic :: Multimedia :: Sound/Audio :: Speech",
|
|
32
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/vox4ai/tts-plugin-edgetts"
|
|
37
|
+
Repository = "https://github.com/vox4ai/tts-plugin-edgetts"
|
|
38
|
+
Issues = "https://github.com/vox4ai/tts-plugin-edgetts/issues"
|
|
39
|
+
|
|
40
|
+
[project.entry-points."tts_bridge.connectors"]
|
|
41
|
+
edgetts = "tts_plugin_edgetts.connector:EdgeTTSConnector"
|
|
42
|
+
|
|
43
|
+
[tool.uv.sources]
|
|
44
|
+
tts-plugin-bridge = { path = "../tts-plugin-bridge", editable = true }
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
dev = [
|
|
48
|
+
"pytest>=9.0.3",
|
|
49
|
+
"pytest-asyncio>=1.3.0",
|
|
50
|
+
"ruff>=0.15.12",
|
|
51
|
+
"build>=1.0",
|
|
52
|
+
"twine>=6.0",
|
|
53
|
+
]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# edgetts_01: tts-plugin-edgetts 設計
|
|
2
|
+
|
|
3
|
+
## 概要
|
|
4
|
+
Microsoft Edge TTS サービスを利用するプラグイン。
|
|
5
|
+
`edge-tts` Python パッケージを内部で呼び出し、`tts-plugin-bridge` の `TTSConnector` に準拠する。
|
|
6
|
+
|
|
7
|
+
## アーキテクチャ
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
tts-plugin-bridge (TTSSkill / ConnectorFactory)
|
|
11
|
+
│
|
|
12
|
+
▼ entry_point: tts_bridge.connectors = edgetts
|
|
13
|
+
tts-plugin-edgetts (EdgeTTSConnector)
|
|
14
|
+
│
|
|
15
|
+
▼
|
|
16
|
+
edge-tts (Communicate / list_voices)
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
Microsoft Edge TTS WebSocket API
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ディレクトリ構成
|
|
23
|
+
```
|
|
24
|
+
tts-plugin-edgetts/
|
|
25
|
+
├── pyproject.toml
|
|
26
|
+
├── AGENTS.md
|
|
27
|
+
├── reports/
|
|
28
|
+
├── tests/
|
|
29
|
+
│ └── test_connector.py
|
|
30
|
+
└── tts_plugin_edgetts/
|
|
31
|
+
├── __init__.py
|
|
32
|
+
└── connector.py
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## EdgeTTSConnector 仕様
|
|
36
|
+
|
|
37
|
+
### クラス定義
|
|
38
|
+
```python
|
|
39
|
+
class EdgeTTSConnector(TTSConnector):
|
|
40
|
+
ENGINE_NAME = "edgetts"
|
|
41
|
+
SUPPORTED_PARAMS = ["voice", "rate", "pitch", "proxy"]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### コンストラクタ
|
|
45
|
+
- `voice: str` — デフォルト `"ja-JP-NanamiNeural"`
|
|
46
|
+
- `rate: str` — デフォルト `"+0%"` (形式: `[+-]N%`)
|
|
47
|
+
- `pitch: str` — デフォルト `"+0Hz"` (形式: `[+-]NHz`)
|
|
48
|
+
- `proxy: Optional[str]` — デフォルト `None`
|
|
49
|
+
|
|
50
|
+
### TTSRequest マッピング
|
|
51
|
+
| TTSRequest フィールド | EdgeTTS パラメータ | 変換ロジック |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `text` | `Communicate(text=...)` | そのまま |
|
|
54
|
+
| `speed` | `rate` | `speed` → パーセント形式 (1.0→"+0%", 1.5→"+50%", 0.5→"-50%") |
|
|
55
|
+
| `volume` | `volume` | `volume` → パーセント形式 (1.0→"+0%", 2.0→"+100%") |
|
|
56
|
+
| `pitch` | `pitch` | そのまま (Hz形式の文字列を想定) |
|
|
57
|
+
| `model` | `voice` | `model` を voice 名として使用 |
|
|
58
|
+
| `extra["voice"]` | `voice` | voice の直接指定 |
|
|
59
|
+
| `extra["rate"]` | `rate` | rate の直接指定 (直接指定優先) |
|
|
60
|
+
| `extra["pitch"]` | `pitch` | pitch の直接指定 (直接指定優先) |
|
|
61
|
+
| `extra["proxy"]` | `proxy` | proxy URL |
|
|
62
|
+
|
|
63
|
+
### synthesize() フロー
|
|
64
|
+
1. TTSRequest からパラメータを変換
|
|
65
|
+
2. `edge_tts.Communicate(text, voice, rate=, volume=, pitch=)` を生成
|
|
66
|
+
3. `stream()` で音声チャンクを収集 (MP3)
|
|
67
|
+
4. 全チャンクを結合して `TTSResponse.ok(audio_data=mp3_bytes)` を返す
|
|
68
|
+
|
|
69
|
+
### is_available() フロー
|
|
70
|
+
1. `edge_tts.list_voices()` を呼び出し
|
|
71
|
+
2. 例外なくレスポンスが返れば `True`、例外なら `False`
|
|
72
|
+
|
|
73
|
+
### 出力フォーマット
|
|
74
|
+
- edge-tts は MP3 (24kHz, 48kbps, mono) を出力
|
|
75
|
+
- `TTSRequest.output_format` が "wav" の場合、`pydub` なしでは変換不可
|
|
76
|
+
- 初期実装では MP3 のまま返却 (metadata に format="mp3" を記録)
|
|
77
|
+
|
|
78
|
+
## 依存関係
|
|
79
|
+
- `tts-plugin-bridge` (path dependency)
|
|
80
|
+
- `edge-tts>=7.0`
|
|
81
|
+
- `aiohttp` (edge-tts 経由)
|
|
82
|
+
|
|
83
|
+
## テスト方針 (TDD / t_wada)
|
|
84
|
+
1. **Red**: 失敗するテストを先に書く
|
|
85
|
+
2. **Green**: テストを通す最小実装
|
|
86
|
+
3. **Refactor**: リファクタリング
|
|
87
|
+
|
|
88
|
+
### テストケース
|
|
89
|
+
- test_connector_is_available_true
|
|
90
|
+
- test_connector_is_available_false
|
|
91
|
+
- test_connector_synthesize_basic
|
|
92
|
+
- test_connector_speed_to_rate_conversion
|
|
93
|
+
- test_connector_volume_to_percent
|
|
94
|
+
- test_connector_model_as_voice
|
|
95
|
+
- test_connector_extra_params_override
|
|
96
|
+
- test_connector_error_handling
|
|
97
|
+
- test_connector_context_manager
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# edgetts_02: 作業ログ 2026-05-08
|
|
2
|
+
|
|
3
|
+
## 作業概要
|
|
4
|
+
vox4ai リポジトリに `tts-plugin-edgetts` を新規作成し、`tts-plugin-bridge` にストリーミング再生機能を追加した。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Phase 1: 調査・設計
|
|
9
|
+
|
|
10
|
+
### コードベース調査
|
|
11
|
+
- `tts-plugin-piperplus` — `PiperPlusConnector` (TTSConnector実装、aiohttp HTTP通信)
|
|
12
|
+
- `tts-plugin-bridge` — `TTSConnector` ABC / `ConnectorFactory` (entry_points発見) / `TTSSkill` (Agent向けラッパー+CLI)
|
|
13
|
+
- `edge-tts` v7.2.8 — `Communicate` クラスの async stream API、`list_voices()`、rate/volume/pitch パラメータ
|
|
14
|
+
|
|
15
|
+
### br (beads-rust) の試行
|
|
16
|
+
- `br init` → SQLite "file-backed pager not available on this platform" エラー
|
|
17
|
+
- Windows環境でbrが動作しないため、`reports/` ディレクトリで代替管理
|
|
18
|
+
|
|
19
|
+
### 設計書
|
|
20
|
+
- `reports/edgetts_01_design.md` にアーキテクチャ・パラメータマッピング・テスト方針を記載
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Phase 2: tts-plugin-edgetts 実装 (TDD)
|
|
25
|
+
|
|
26
|
+
### プロジェクトスケルトン
|
|
27
|
+
```
|
|
28
|
+
tts-plugin-edgetts/
|
|
29
|
+
├── pyproject.toml # entry_point: tts_bridge.connectors = edgetts
|
|
30
|
+
├── AGENTS.md
|
|
31
|
+
├── README.md
|
|
32
|
+
├── .gitignore
|
|
33
|
+
├── LICENSE
|
|
34
|
+
├── reports/
|
|
35
|
+
│ └── edgetts_01_design.md
|
|
36
|
+
├── tests/
|
|
37
|
+
│ ├── test_connector.py
|
|
38
|
+
│ └── test_integration.py
|
|
39
|
+
└── tts_plugin_edgetts/
|
|
40
|
+
├── __init__.py
|
|
41
|
+
└── connector.py
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### TDD Red → Green → Refactor
|
|
45
|
+
|
|
46
|
+
**Red**: 14テストを先に記述 (importエラーで失敗確認)
|
|
47
|
+
**Green**: `EdgeTTSConnector` 最小実装で14/14通過
|
|
48
|
+
**Refactor**: `_build_params()` 抽出、ruff format適用
|
|
49
|
+
|
|
50
|
+
### EdgeTTSConnector 仕様
|
|
51
|
+
| パラメータ | デフォルト | 変換ロジック |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `voice` | `ja-JP-NanamiNeural` | `TTSRequest.model` or `extra["voice"]` で上書き |
|
|
54
|
+
| `rate` | `+0%` | `speed` → `round((speed-1)*100)` → `±N%` |
|
|
55
|
+
| `volume` | `+0%` | `volume` → `round((volume-1)*100)` → `±N%` |
|
|
56
|
+
| `pitch` | `+0Hz` | `extra["pitch"]` で直接指定 |
|
|
57
|
+
| `proxy` | None | `extra["proxy"]` で指定 |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Phase 3: 結合試験
|
|
62
|
+
|
|
63
|
+
`test_integration.py` で bridge 経由の動作を6テスト検証:
|
|
64
|
+
- `ConnectorFactory.list_available()` に "edgetts" が含まれる
|
|
65
|
+
- `ConnectorFactory.create("edgetts")` → `EdgeTTSConnector` インスタンス
|
|
66
|
+
- `TTSSkill.synthesize()` → base64音声データ返却
|
|
67
|
+
- speed/volume パラメータ変換の確認
|
|
68
|
+
- エンジン unavailable 時のエラーハンドリング
|
|
69
|
+
- entry_points 登録の確認
|
|
70
|
+
|
|
71
|
+
### 実発声テスト
|
|
72
|
+
3パターンのMP3生成 + Windowsプレーヤーで再生確認:
|
|
73
|
+
- edge-tts直接: 24KB
|
|
74
|
+
- EdgeTTSConnector経由: 28KB
|
|
75
|
+
- speed=1.3, volume=1.5, KeitaNeural: 14KB
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Phase 4: ストリーミング再生対応 (要望対応)
|
|
80
|
+
|
|
81
|
+
### 追加要件
|
|
82
|
+
1. bridge が ffplay を subprocess で呼んで再生
|
|
83
|
+
2. edgetts のストリーミング再生を活かしたパイプ渡し
|
|
84
|
+
|
|
85
|
+
### tts-plugin-bridge 変更点
|
|
86
|
+
|
|
87
|
+
**protocol.py**:
|
|
88
|
+
- `TTSConnector.synthesize_stream()` 追加 — デフォルト実装(一括yield)付きasync generator
|
|
89
|
+
- 型ヒントに `AsyncGenerator` 追加
|
|
90
|
+
|
|
91
|
+
**skill.py**:
|
|
92
|
+
- `TTSSkill.play()` 追加 — ストリーミング合成→ffplay stdin パイプ再生
|
|
93
|
+
- `shutil.which("ffplay")` で自動検索、`player` 引数で上書き可能
|
|
94
|
+
- `FileNotFoundError` ハンドリング追加
|
|
95
|
+
- CLI `play` サブコマンド追加
|
|
96
|
+
```
|
|
97
|
+
tts-plugin-bridge play "こんにちは" -e edgetts
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### tts-plugin-edgetts 変更点
|
|
101
|
+
|
|
102
|
+
**connector.py**:
|
|
103
|
+
- `_build_params()` にリファクタリング (synthesize/synthesize_stream 共用)
|
|
104
|
+
- `synthesize_stream()` オーバーライド — edge-ttsの `Communicate.stream()` からaudioチャンクを直接yield
|
|
105
|
+
- バッファなしでffplayにストリーミング
|
|
106
|
+
|
|
107
|
+
### データフロー
|
|
108
|
+
```
|
|
109
|
+
TTSSkill.play()
|
|
110
|
+
→ EdgeTTSConnector.synthesize_stream()
|
|
111
|
+
→ edge_tts.Communicate.stream()
|
|
112
|
+
→ MP3チャンク yield (720B/チャンク)
|
|
113
|
+
→ subprocess.stdin.write(chunk)
|
|
114
|
+
→ ffplay -nodisp -autoexit -i pipe:0
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### ストリーミングテスト追加
|
|
118
|
+
- bridge: `test_play.py` 5テスト (Popenモック、ffplay不在、エンジン不可、デフォルトストリーム)
|
|
119
|
+
- edgetts: `test_connector.py` 2テスト追加 (チャンクyield確認、パラメータ引継ぎ)
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 最終テスト結果
|
|
124
|
+
|
|
125
|
+
| パッケージ | テスト数 | 結果 |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| tts-plugin-bridge | 16 | 16 passed |
|
|
128
|
+
| tts-plugin-edgetts | 22 | 22 passed |
|
|
129
|
+
| **合計** | **38** | **38 passed** |
|
|
130
|
+
|
|
131
|
+
lint: ruff check 全通過 / format: ruff format 適用済み
|
|
132
|
+
|
|
133
|
+
### 実発声確認
|
|
134
|
+
- `skill.play()` → ffplay経由で35チャンクストリーミング再生 OK
|
|
135
|
+
- CLI `tts-plugin-bridge play "..." -e edgetts` → 36チャンク再生 OK
|