@rookiestar/eng-lang-tutor 1.1.3 → 1.1.5

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.

Potentially problematic release.


This version of @rookiestar/eng-lang-tutor might be problematic. Click here for more details.

package/README.md CHANGED
@@ -103,7 +103,16 @@ openclaw pairing approve discord YOUR_PAIRING_CODE
103
103
  3. 选择导师风格(幽默/严谨/随意/专业)
104
104
  4. 设置口语/书面语比例
105
105
  5. 配置推送时间(知识点和测验时间)
106
- 6. 选择是否启用语音教学,如启用可调节语速
106
+ 6. **语音教学配置** - 选择是否启用语音版知识点
107
+ - 如启用,选择语速(0.5-1.7,默认 0.9)
108
+ - 默认使用 Edge-TTS(免费,无需配置)
109
+ - 如需使用讯飞,请先在服务器上设置环境变量:
110
+ ```bash
111
+ export TTS_PROVIDER=xunfei
112
+ export XUNFEI_APPID=your_appid
113
+ export XUNFEI_API_KEY=your_api_key
114
+ export XUNFEI_API_SECRET=your_api_secret
115
+ ```
107
116
  7. 确认您的设置并创建定时任务
108
117
 
109
118
  ## TTS 语音配置
@@ -255,7 +264,16 @@ eng-lang-tutor/
255
264
  │ ├── constants.py # 共享常量(等级阈值)
256
265
  │ ├── utils.py # 工具函数(安全除法、深度合并)
257
266
  │ ├── cli.py # CLI 入口点
258
- │ └── tts/ # TTS 语音合成模块
267
+ │ └── audio/ # 音频模块
268
+ │ ├── tts/ # TTS 语音合成
269
+ │ │ ├── base.py # TTS 抽象基类
270
+ │ │ ├── manager.py # TTS 管理器
271
+ │ │ └── providers/ # TTS 提供者
272
+ │ │ ├── edge.py # Edge-TTS (默认)
273
+ │ │ └── xunfei.py # 讯飞 TTS
274
+ │ ├── composer.py # 音频合成
275
+ │ ├── converter.py # 格式转换
276
+ │ └── feishu_voice.py # 飞书语音发送
259
277
  ├── templates/
260
278
  │ ├── state_schema.json # 状态 JSON Schema
261
279
  │ ├── keypoint_schema.json # 知识点 JSON Schema
package/README_EN.md CHANGED
@@ -103,7 +103,16 @@ When you first interact with the bot, it will guide you through a 7-step onboard
103
103
  3. Select tutor style (humorous/rigorous/casual/professional)
104
104
  4. Set oral vs written focus
105
105
  5. Configure schedule (keypoint and quiz times)
106
- 6. Choose whether to enable voice teaching, adjust speed if enabled
106
+ 6. **Voice Teaching Configuration** - Choose whether to enable audio keypoints
107
+ - If enabled, select speech speed (0.5-1.7, default 0.9)
108
+ - Edge-TTS is used by default (free, no configuration needed)
109
+ - To use XunFei, set environment variables on your server first:
110
+ ```bash
111
+ export TTS_PROVIDER=xunfei
112
+ export XUNFEI_APPID=your_appid
113
+ export XUNFEI_API_KEY=your_api_key
114
+ export XUNFEI_API_SECRET=your_api_secret
115
+ ```
107
116
  7. Confirm your settings and create cron jobs
108
117
 
109
118
  ## TTS Voice Configuration
@@ -255,7 +264,16 @@ eng-lang-tutor/
255
264
  │ ├── constants.py # Shared constants (level thresholds)
256
265
  │ ├── utils.py # Utility functions (safe divide, deep merge)
257
266
  │ ├── cli.py # CLI entry point
258
- │ └── tts/ # TTS module
267
+ │ └── audio/ # Audio module
268
+ │ ├── tts/ # TTS voice synthesis
269
+ │ │ ├── base.py # TTS abstract base class
270
+ │ │ ├── manager.py # TTS manager
271
+ │ │ └── providers/ # TTS providers
272
+ │ │ ├── edge.py # Edge-TTS (default)
273
+ │ │ └── xunfei.py # XunFei TTS
274
+ │ ├── composer.py # Audio composition
275
+ │ ├── converter.py # Format conversion
276
+ │ └── feishu_voice.py # Feishu voice sender
259
277
  ├── templates/
260
278
  │ ├── state_schema.json # State JSON Schema
261
279
  │ ├── keypoint_schema.json # Keypoint JSON Schema
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rookiestar/eng-lang-tutor",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "English language tutor skill for OpenClaw - Learn authentic American English expressions with gamification",
5
5
  "keywords": [
6
6
  "english",
@@ -10,7 +10,7 @@ TTS 管理器 - 通用入口,支持多 Provider
10
10
 
11
11
  # 方式 2:直接传入讯飞密钥
12
12
  manager = TTSManager(
13
- provider="xunfei",
13
+ provider="edge-tts",
14
14
  appid="xxx",
15
15
  api_key="xxx",
16
16
  api_secret="xxx"
@@ -33,6 +33,7 @@ import sys
33
33
  sys.path.insert(0, str(Path(__file__).parent.parent.parent))
34
34
 
35
35
  from .base import TTSProvider, TTSConfig, TTSResult
36
+ from .providers.edge import EdgeTTSProvider
36
37
  from .providers.xunfei import XunFeiProvider
37
38
 
38
39
  try:
@@ -43,10 +44,8 @@ except ImportError:
43
44
 
44
45
  # Provider 注册表
45
46
  PROVIDERS: Dict[str, Type[TTSProvider]] = {
47
+ "edge-tts": EdgeTTSProvider,
46
48
  "xunfei": XunFeiProvider,
47
- # 可扩展更多 provider
48
- # "edge-tts": EdgeTTSProvider,
49
- # "minimax": MiniMaxProvider,
50
49
  }
51
50
 
52
51
 
@@ -65,7 +64,7 @@ class TTSManager:
65
64
 
66
65
  def __init__(
67
66
  self,
68
- provider: str = "xunfei",
67
+ provider: str = "edge-tts",
69
68
  data_dir: str = None,
70
69
  config: Optional[TTSConfig] = None,
71
70
  **credentials
@@ -74,16 +73,16 @@ class TTSManager:
74
73
  初始化 TTS 管理器
75
74
 
76
75
  Args:
77
- provider: Provider 名称(目前仅支持 "xunfei")
76
+ provider: Provider 名称(支持 "edge-tts" 或 "xunfei")
78
77
  data_dir: 数据目录(默认使用 OPENCLAW_STATE_DIR 或 ~/.openclaw/state/eng-lang-tutor/)
79
78
  config: TTS 配置
80
79
  **credentials: Provider 认证信息
81
80
 
82
81
  示例:
83
- # 讯飞(使用默认数据目录)
84
- manager = TTSManager(provider="xunfei")
82
+ # Edge-TTS(免费,无需密钥)
83
+ manager = TTSManager(provider="edge-tts")
85
84
 
86
- # 讯飞(直接传入密钥)
85
+ # 讯飞(国内稳定)
87
86
  manager = TTSManager(
88
87
  provider="xunfei",
89
88
  appid="xxx",
@@ -121,6 +120,10 @@ class TTSManager:
121
120
  从环境变量创建 TTS 管理器
122
121
 
123
122
  环境变量格式:
123
+ # Edge-TTS(默认,免费无需配置)
124
+ TTS_PROVIDER=edge-tts
125
+
126
+ # 讯飞(需配置密钥)
124
127
  TTS_PROVIDER=xunfei
125
128
  XUNFEI_APPID=xxx
126
129
  XUNFEI_API_KEY=xxx
@@ -133,7 +136,7 @@ class TTSManager:
133
136
  Returns:
134
137
  TTSManager 实例
135
138
  """
136
- provider = provider or os.getenv("TTS_PROVIDER", "xunfei")
139
+ provider = provider or os.getenv("TTS_PROVIDER", "edge-tts")
137
140
  return cls(provider=provider, **kwargs)
138
141
 
139
142
  def switch_provider(self, provider: str, **credentials) -> None:
@@ -3,8 +3,10 @@
3
3
  TTS Providers - TTS 服务提供者实现
4
4
  """
5
5
 
6
+ from .edge import EdgeTTSProvider
6
7
  from .xunfei import XunFeiProvider
7
8
 
8
9
  __all__ = [
10
+ "EdgeTTSProvider",
9
11
  "XunFeiProvider",
10
12
  ]
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Edge-TTS Provider 实现
4
+
5
+ Microsoft Edge TTS 服务:
6
+ - 完全免费,无需 API 密钥
7
+ - 高质量 24kHz 神经语音
8
+ - 支持多种美式英语发音人
9
+ - 国内网络可能需要代理
10
+ """
11
+
12
+ import asyncio
13
+ import edge_tts
14
+ from pathlib import Path
15
+ from typing import Optional, ClassVar, Dict
16
+
17
+ from ..base import TTSProvider, TTSConfig, TTSResult
18
+
19
+
20
+ class EdgeTTSProvider(TTSProvider):
21
+ """
22
+ Microsoft Edge TTS Provider
23
+
24
+ 支持的美式英语发音人:
25
+ - en-US-JennyNeural: 女声,友好亲切(推荐)
26
+ - en-US-AriaNeural: 女声,自信清晰
27
+ - en-US-EricNeural: 男声,专业理性(推荐)
28
+ - en-US-GuyNeural: 男声,热情活力
29
+ - en-US-AnaNeural: 女声,可爱随和
30
+ - en-US-ChristopherNeural: 男声,权威可靠
31
+
32
+ 无需认证信息,直接使用。
33
+ """
34
+
35
+ PROVIDER_NAME: ClassVar[str] = "edge-tts"
36
+ DEFAULT_FEMALE_VOICE: ClassVar[str] = "en-US-JennyNeural" # 友好亲切
37
+ DEFAULT_MALE_VOICE: ClassVar[str] = "en-US-EricNeural" # 专业理性
38
+ # 角色音色映射:旁白-女声,对话A-男声,对话B-女声
39
+ DEFAULT_NARRATOR_VOICE: ClassVar[str] = "en-US-JennyNeural" # 旁白 - 女声
40
+ DEFAULT_DIALOGUE_A_VOICE: ClassVar[str] = "en-US-EricNeural" # 对话 A - 男声
41
+ DEFAULT_DIALOGUE_B_VOICE: ClassVar[str] = "en-US-JennyNeural" # 对话 B - 女声
42
+
43
+ SUPPORTED_VOICES: ClassVar[Dict[str, str]] = {
44
+ "en-US-JennyNeural": "美式英语女声,友好亲切(推荐)",
45
+ "en-US-AriaNeural": "美式英语女声,自信清晰",
46
+ "en-US-EricNeural": "美式英语男声,专业理性(推荐)",
47
+ "en-US-GuyNeural": "美式英语男声,热情活力",
48
+ "en-US-AnaNeural": "美式英语女声,可爱随和",
49
+ "en-US-ChristopherNeural": "美式英语男声,权威可靠",
50
+ "en-US-MichelleNeural": "美式英语女声,友好舒适",
51
+ "en-US-RogerNeural": "美式英语男声,生动活泼",
52
+ "en-US-AndrewNeural": "美式英语男声,友好积极",
53
+ "en-US-BrianNeural": "美式英语男声,友好积极",
54
+ "en-US-EmmaNeural": "美式英语女声,友好积极",
55
+ "en-US-AvaNeural": "美式英语女声,友好积极",
56
+ }
57
+
58
+ def _validate_credentials(self) -> None:
59
+ """
60
+ 验证认证信息
61
+
62
+ Edge-TTS 不需要认证信息,直接通过。
63
+ """
64
+ # Edge-TTS 不需要任何认证信息
65
+ pass
66
+
67
+ def synthesize(
68
+ self,
69
+ text: str,
70
+ output_path: Path,
71
+ voice: Optional[str] = None,
72
+ speed: Optional[float] = None
73
+ ) -> TTSResult:
74
+ """
75
+ 合成语音
76
+
77
+ Args:
78
+ text: 要合成的文本
79
+ output_path: 输出文件路径(.mp3)
80
+ voice: 语音 ID(可选,默认使用女声)
81
+ speed: 语速(可选,0.5-2.0,1.0 = 正常)
82
+
83
+ Returns:
84
+ TTSResult: 合成结果
85
+ """
86
+ voice = voice or self.get_voice("female")
87
+ speed_val = speed or self.config.speed
88
+
89
+ # 将 speed (0.5-2.0) 转换为 edge-tts 的 rate 格式
90
+ # speed=1.0 -> rate="+0%"
91
+ # speed=0.7 -> rate="-30%" (更慢,适合学习)
92
+ # speed=1.5 -> rate="+50%" (更快)
93
+ rate_percent = int((speed_val - 1.0) * 100)
94
+ rate = f"{rate_percent:+d}%"
95
+
96
+ # 确保输出目录存在
97
+ output_path = Path(output_path)
98
+ output_path.parent.mkdir(parents=True, exist_ok=True)
99
+
100
+ async def _synthesize_async():
101
+ """异步合成语音"""
102
+ communicate = edge_tts.Communicate(text, voice, rate=rate)
103
+ await communicate.save(str(output_path))
104
+
105
+ try:
106
+ # 在同步上下文中运行异步代码
107
+ asyncio.run(_synthesize_async())
108
+ return TTSResult(success=True, audio_path=output_path)
109
+
110
+ except Exception as e:
111
+ return TTSResult(success=False, error_message=str(e))