tts-plugin-edgetts 0.1.0__py3-none-any.whl

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,3 @@
1
+ from .connector import EdgeTTSConnector
2
+
3
+ __all__ = ["EdgeTTSConnector"]
@@ -0,0 +1,86 @@
1
+ from typing import AsyncGenerator, Optional
2
+
3
+ import edge_tts
4
+ from tts_plugin_bridge.protocol import TTSConnector, TTSRequest, TTSResponse
5
+
6
+
7
+ class EdgeTTSConnector(TTSConnector):
8
+ ENGINE_NAME = "edgetts"
9
+ SUPPORTED_PARAMS = ["voice", "rate", "pitch", "proxy"]
10
+
11
+ def __init__(
12
+ self,
13
+ voice: str = "ja-JP-NanamiNeural",
14
+ rate: str = "+0%",
15
+ pitch: str = "+0Hz",
16
+ proxy: Optional[str] = None,
17
+ ):
18
+ self.voice = voice
19
+ self.rate = rate
20
+ self.pitch = pitch
21
+ self.proxy = proxy
22
+
23
+ @staticmethod
24
+ def _speed_to_rate(speed: float) -> str:
25
+ percent = round((speed - 1.0) * 100)
26
+ return f"{percent:+d}%"
27
+
28
+ @staticmethod
29
+ def _volume_to_percent(volume: float) -> str:
30
+ percent = round((volume - 1.0) * 100)
31
+ return f"{percent:+d}%"
32
+
33
+ def _build_params(self, req: TTSRequest) -> dict:
34
+ voice = req.extra.get("voice") or req.model or self.voice
35
+ rate = req.extra.get("rate") or self._speed_to_rate(req.speed)
36
+ pitch = req.extra.get("pitch") or self.pitch
37
+ volume = self._volume_to_percent(req.volume) if req.volume else "+0%"
38
+ proxy = req.extra.get("proxy") or self.proxy
39
+ return {
40
+ "voice": voice,
41
+ "rate": rate,
42
+ "pitch": pitch,
43
+ "volume": volume,
44
+ "proxy": proxy,
45
+ }
46
+
47
+ async def synthesize(self, req: TTSRequest) -> TTSResponse:
48
+ try:
49
+ params = self._build_params(req)
50
+ communicate = edge_tts.Communicate(req.text, **params)
51
+
52
+ audio_chunks: list[bytes] = []
53
+ async for chunk in communicate.stream():
54
+ if chunk["type"] == "audio":
55
+ audio_chunks.append(chunk["data"])
56
+
57
+ if not audio_chunks:
58
+ return TTSResponse.fail("No audio data received from edge-tts")
59
+
60
+ audio_data = b"".join(audio_chunks)
61
+ return TTSResponse.ok(audio_data=audio_data, metadata={"format": "mp3"})
62
+ except Exception as e:
63
+ return TTSResponse.fail(f"{type(e).__name__}: {e}")
64
+
65
+ async def synthesize_stream(self, req: TTSRequest) -> AsyncGenerator[bytes, None]:
66
+ params = self._build_params(req)
67
+ communicate = edge_tts.Communicate(req.text, **params)
68
+ async for chunk in communicate.stream():
69
+ if chunk["type"] == "audio":
70
+ yield chunk["data"]
71
+
72
+ async def is_available(self) -> bool:
73
+ try:
74
+ await edge_tts.list_voices()
75
+ return True
76
+ except Exception:
77
+ return False
78
+
79
+ async def close(self):
80
+ pass
81
+
82
+ async def __aenter__(self):
83
+ return self
84
+
85
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
86
+ await self.close()
@@ -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,7 @@
1
+ tts_plugin_edgetts/__init__.py,sha256=4OIoBm__Vwd-Y3kudEJwMXAUZJozZrO6PixiUgjwTJY,72
2
+ tts_plugin_edgetts/connector.py,sha256=80xPL-nMltFJ13mwsNRE_W0qqXHoHW5VKN-J4kgTNb4,2778
3
+ tts_plugin_edgetts-0.1.0.dist-info/METADATA,sha256=t8UHPah_MbhADWEFY_aNVJBb1fvDMOBwn1b0s9_BSFQ,5532
4
+ tts_plugin_edgetts-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
5
+ tts_plugin_edgetts-0.1.0.dist-info/entry_points.txt,sha256=_3VdHQZNdyipE_ZRdZYRYXlMWPIqSJtwd7lBIuI6lx0,80
6
+ tts_plugin_edgetts-0.1.0.dist-info/licenses/LICENSE,sha256=RnwZkqBFkeDYZDf3AlIh-qwLMPsJJajhB2YwaRRDWMU,1062
7
+ tts_plugin_edgetts-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [tts_bridge.connectors]
2
+ edgetts = tts_plugin_edgetts.connector:EdgeTTSConnector
@@ -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.