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.
@@ -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