dsh-avatar-frame 0.11.6 → 0.14.1

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.
package/CHANGELOG.md CHANGED
@@ -1,7 +1,331 @@
1
+ ## [0.14.1] - 2026-10-28
2
+
3
+ ### 修复
4
+
5
+ - 音色选「系统语音」时仍然显示「试听一句」——那是走本地服务的试听,和系统语音的音色试听重复了。
6
+ 现在三处(设置页、插件详情页、头像弹窗)都只在「本地服务」下显示它;
7
+ 系统语音的音色试听保留在音色选择那一行。
8
+
9
+ ## [0.14.0] - 2026-10-28
10
+
11
+ 自 0.11.6 起的第一个公开发布版本,集中了这几天的功能与修复:
12
+
13
+ ### 新增
14
+
15
+ - 自动朗读新回复(可关;切到别的会话不会突然开口,新回复出现才念;新回复会打断正在念的旧回复)
16
+ - 系统语音可选音色(按回复语言自动选中/英文音色,优先神经网络音色),带试听
17
+ - 音量滑块(0–100%,默认 50%),两种引擎都生效
18
+ - 系统语音也支持暂停 / 继续 / 上一句 / 下一句 / 语速 / 停止
19
+ - 语音服务「重启」按钮
20
+ - 试听入口扩到三处:设置页、插件详情页、头像弹窗;两种引擎都能试听
21
+ - 启动暖机期:点启动后显示「检测中 · 已等待 N 秒」,连上再变「已连接」
22
+ - 失败原因短提示(超时 / 连不上 / HTTP 状态码),限长不撑破界面
23
+
24
+ ### 修复
25
+
26
+ - 点开头像 / 详情页 / 设置页会卡死(音色列表在渲染期间写 store,形成无限重渲染)
27
+ - 离线重试从未生效(调度一直以 attempt=0 重启,界面进不了「未连接」)
28
+ - 切会话时声音不停、控制条消失(系统语音 不可靠,补 + 二次 )
29
+ - 试听无反应(会话守卫误杀试听;AudioContext 挂起;直连被浏览器拦截)
30
+ - 音量未设置时被当成 0(默认静音)
31
+ - 自动朗读用系统语音念本地服务的内容(未按引擎分流)
32
+ - 弹窗里系统语音一行挤爆(改竖排 + 弹窗加宽)
33
+
34
+ ### 工程
35
+
36
+ - 设置页与插件详情页共用 / ,内容不会再走偏
37
+ - 行组件订阅收窄,改 ID / 播放进度不再重渲染所有历史轮次
38
+ - 宿主端新增 TTS 转发与诊断日志()
1
39
  # 更新记录
2
40
 
3
41
  格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
4
42
 
43
+ ## [0.13.18] - 2026-10-28
44
+
45
+ ### 修复
46
+
47
+ - **跨段误取消**:直连 `/tts` 用的是全局 `speechRun.controller`,某一段 1.5 秒超时时
48
+ 会把同时进行中的其它段一起中止。现在每次请求用独立 AbortController,只跟随整体停止信号。
49
+ - 删掉未使用的文案键 `audition.stopHint`(字典两边同时清理,101 键仍对齐)。
50
+
51
+ ## [0.13.17] - 2026-10-28
52
+
53
+ ### 变更
54
+
55
+ - 设置页与插件详情页的「朗读 / 语音服务 / 诊断」抽成共用组件(`SpeechSettings`、`DiagnosticsBlock`),
56
+ 两边从此显示同一份内容,不会再出现改了一边、另一边落后的情况。
57
+ - 详情页补上了状态点(已连接/未连接 + 模型名 + 等待/失败小字)与诊断信息。
58
+ - 清理了设置页里因此不再使用的局部变量。
59
+
60
+ ## [0.13.16] - 2026-10-28
61
+
62
+ ### 变更
63
+
64
+ - 自动朗读的判定简化为「只念新出现的回复」:
65
+ - 切进一个会话时,把它当前最新一轮记为基线,**已有的内容不念**;
66
+ - 之后你发消息、AI 回复产生的新轮次,**照常自动朗读**,不需要再点小喇叭;
67
+ - 上一轮还没念完时来了新回复,仍然打断并改念新的。
68
+ - 去掉了 0.13.15 里「必须点过小喇叭才生效」的会话授权逻辑(它会让新会话的回复也不念)。
69
+
70
+ ## [0.13.15] - 2026-10-28
71
+
72
+ ### 变更
73
+
74
+ - **新回复优先**:上一轮还没念完就来了新回复时,直接打断旧朗读、改念新的
75
+ (原来是排队等旧的念完,导致新回复被跳过、耳朵里还是旧内容)。
76
+ - **切换会话不再自动朗读**:切过去的会话默认安静;只有在该会话里**手动点过小喇叭**之后,
77
+ 这个会话才会自动朗读后续回复。打开自动朗读开关时,当前会话直接生效。
78
+
79
+ ## [0.13.14] - 2026-10-28
80
+
81
+ ### 修复
82
+
83
+ - 停止朗读时没把「等待中的合成请求」计数归零,一个卡死的旧请求会让看门狗永久失效。
84
+ - 换服务地址后重新尝试直连(之前失败过就永久走宿主代理,换了地址其实可能又通)。
85
+ - 「试听失败」只显示试听自身的错误:聊天里某句朗读失败,不该在设置页显示成试听失败。
86
+ - 自动朗读遇到「别的声音还在播」时,改成排队等它结束(最多重试 20 次),
87
+ 而不是把这一轮直接标记成已念、结果什么都没念。
88
+
89
+ ## [0.13.13] - 2026-10-28
90
+
91
+ ### 新增
92
+
93
+ - 点头像弹出的面板里也加了「试听一句」,位置在音色选择下面;
94
+ 两种引擎都可用(本地服务走语音服务,系统语音走浏览器音色),失败原因同样显示在按钮旁边。
95
+ - 设置页与插件详情页的试听不再只在「本地服务」下出现,系统语音也能试听。
96
+
97
+ ## [0.13.12] - 2026-10-28
98
+
99
+ ### 修复
100
+
101
+ - 出声前会闪一下「试听失败:playback did not start」:看门狗在等待合成(直连 6 秒超时)期间
102
+ 误判成卡住。现在有请求在等时不算卡住,并且真正开始出声时会清掉旧错误。
103
+ - 直连超时从 6 秒缩到 **1.5 秒**:dsh-app:// 页面访问 127.0.0.1 基本都会被拦,早点转宿主代理,
104
+ 第一次出声的等待时间明显变短。
105
+ - 「试听失败」这行小字和右边的「已连接」没有对齐:补上 `margin-top:0` 与居中。
106
+
107
+ ## [0.13.11] - 2026-10-28
108
+
109
+ ### 修复
110
+
111
+ - 试听被聊天行的「换会话就停」逻辑误杀:试听的 sessionId 是 null,不属于任何会话,
112
+ 却被判成「别的会话在播」,刚发起就被 stopSpeech 取消(日志里停在 `clone: ctx=running`,
113
+ 连 `tts: post` 都没打出来)。现在 sessionId 为 null 时不再被行组件停止。
114
+ - 直连失败过一次后记住结果,后续段落直接走宿主代理,不再每段都等 6 秒超时。
115
+
116
+ ## [0.13.10] - 2026-10-28
117
+
118
+ ### 新增
119
+
120
+ - **宿主端 TTS 代理**:`POST /dsh-avatar-frame/service {action:"tts"}`,由宿主进程去请求本机语音服务,
121
+ 绕开浏览器对 `dsh-app:// → http://127.0.0.1` 的网络限制。
122
+ - 客户端直连 `/tts` 超过 6 秒或失败时,自动改用宿主代理,并在日志里记下 `tts: direct failed → host proxy`。
123
+
124
+ ## [0.13.9] - 2026-10-28
125
+
126
+ ### 修复
127
+
128
+ - 从设置页点试听时请求一直挂起(日志停在 `clone: ctx=running` 之后,没有 `tts` 结果):
129
+ DSH 页面的来源是 `dsh-app://`,向 `http://127.0.0.1` 发带 JSON 的 POST 会触发 Chromium 的
130
+ **Private Network Access** 预检,缺少 `Access-Control-Allow-Private-Network` 时请求会被拦下。
131
+ 本例里服务端已补上该响应头。
132
+ - 客户端给 `/tts` 加了 90 秒超时与更细的诊断(请求 URL、状态码、字节数、失败原因),
133
+ 再出现挂起会以错误形式暴露,而不是无声无息。
134
+
135
+ ## [0.13.8] - 2026-10-28
136
+
137
+ ### 诊断
138
+
139
+ - 宿主端新增 `action: "debug"`,把信息追加到 `~/.dsh/storages/dsh-avatar-frame/debug.log`;
140
+ - 客户端在试听/播放的关键节点写诊断行(点击是否到达、文本与引擎、chunks 数、音频上下文状态、
141
+ 每段字节数与解码时长、播放完成、异常)。用于定位「设置页点试听没反应」。
142
+
143
+ ## [0.13.7] - 2026-10-28
144
+
145
+ ### 修复
146
+
147
+ - 开了自动朗读、音色选「本地服务」时,新回复却用**系统语音**念:自动朗读的兜底分支无条件调用了
148
+ `startSpeech`(系统语音)。现在按当前引擎分流:本地服务走 `speakClone`,系统语音走 `startSpeech`。
149
+
150
+ ## [0.13.6] - 2026-10-28
151
+
152
+ ### 修复
153
+
154
+ - 点「试听一句」先广播「试听中」,再去做需要 await 的准备(音频上下文恢复等);
155
+ `ctx.resume()` 加 1.5 秒上限,避免某一步挂起时表现成「点了完全没反应」。
156
+ - 试听按钮阻止 `mousedown`/`pointerdown` 冒泡,避免被设置弹窗的外层处理吃掉首次点击
157
+ (表现为:设置页第一次点没反应,去插件页点一次、回来再点就正常)。
158
+
159
+ ## [0.13.5] - 2026-10-28
160
+
161
+ ### 修复
162
+
163
+ - 「试听一句」点了没声音:浏览器的 AudioContext 在没拿到用户手势时会处于 `suspended`,
164
+ 此时 `source.start()` 不出声、`onended` 也不触发,状态就永远卡在 speaking。
165
+ 现在播放前会 `await ctx.resume()`,并确认 `state === running`,否则按失败上报。
166
+ - 加了播放看门狗:状态是「在播」但既没有音频源、浏览器也没在说话,超过 3 秒自动复位并记录失败原因。
167
+
168
+ ## [0.13.4] - 2026-10-28
169
+
170
+ ### 新增
171
+
172
+ - 试听按钮旁边会显示状态:「试听中 n/m」,失败时显示「试听失败:原因」(红色小字,限长)。
173
+ 之前点了没反应时完全没有线索,现在能直接看出是没请求到、还是解码/播放出了问题。
174
+
175
+ ## [0.13.3] - 2026-10-28
176
+
177
+ ### 修复
178
+
179
+ - 点「试听一句」没反应:
180
+ - 按钮在播放状态残留成 speaking 时会被禁用,而那个状态可能已经没有声音在放;
181
+ 现在永远可点,点了先停干净再从头念。
182
+ - 系统语音在 `stopSpeech` 里被 `pause()` 过,Chromium 会一直保持暂停态,
183
+ 后续 `speak()` 只入队不出声;现在每次开口前先 `resume()`。
184
+ - 系统语音试听的音量跟随音量设置(之前固定 100%)。
185
+
186
+ ## [0.13.2] - 2026-10-28
187
+
188
+ ### 修复
189
+
190
+ - 打开「自动朗读新回复」会**立刻**念当前最新一条:基线取的是第一行的轮次,后面所有轮都算"新"。
191
+ 现在按会话延后 400ms 取"当前最新一轮"作基线,只念之后出现的新回复;关掉再打开会重取基线。
192
+ - 切到别的对话再切回来,出现「控制条消失、小喇叭没亮,但声音还在播」:
193
+ 换会话的停止判断只看 sessionId,状态变化时不会触发;现在监听播放状态,并给系统语音补了
194
+ `pause()` + 两次 `cancel()`(Chromium 的 cancel 偶尔只清队列、不停当前句)。
195
+
196
+ ## [0.13.1] - 2026-10-28
197
+
198
+ ### 修复
199
+
200
+ - **音量默认值**:没设置过时被当成 0(等于默认静音),现在默认 **50%**;显式存 0 才是静音。
201
+ - 自动朗读用了占位的 sessionId,行组件认不出「正在念」,从控制条上看不到播放状态;改用真实 sessionId。
202
+ - 系统语音暂停时点「下一句」,暂停标记没有清掉,新句子一开口就是暂停态。
203
+ - 设置页漏了「自动朗读新回复」和「音量」两项(只加到了详情页和弹窗)。
204
+ - 行组件的订阅范围收窄:以前**每一轮**都订阅整个头像/播放状态,改 ID、调整进度会让所有历史行重渲染;
205
+ 现在只有它用到的字段变化才重渲染。
206
+
207
+ ## [0.13.0] - 2026-10-28
208
+
209
+ ### 新增
210
+
211
+ - **自动朗读新回复**:设置页与详情页都有开关;打开后新一轮回复结束会自动念,
212
+ 打开界面时已存在的历史轮次不会被念。
213
+ - **系统语音也有播放控制**:暂停/继续、上一句/下一句、五档语速、停止。系统语音改为按句播放,
214
+ 与本地服务共用同一条控制条。
215
+ - **音量滑块**(0–100%):系统语音与本地服务都生效。
216
+ - **重启服务**按钮:先停再起,不用手动点两次。
217
+
218
+ ## [0.12.8] - 2026-10-28
219
+
220
+ ### 修复
221
+
222
+ - 「未连接 / 检测中」和它右边那句原因没有对齐:详情那行原本带 `margin-top:6px`,
223
+ 在横向排列里把它压低了几像素。改成两者包进同一个 flex 行、居中对齐、间距 8px。
224
+
225
+ ## [0.12.7] - 2026-10-28
226
+
227
+ ### 变更
228
+
229
+ - 等待/失败的提示只保留一处(试听按钮旁边),去掉地址框下面重复的那一条。
230
+ - 连接失败时在同一行给出**简短原因**:连接超时 / 连不上服务 / 服务返回 HTTP 状态码;
231
+ 文案限长(超 70 字截断)并用省略号收尾,避免长原因撑破界面。
232
+
233
+ ## [0.12.6] - 2026-10-28
234
+
235
+ ### 变更
236
+
237
+ - 点「启动服务」后不再闪一下「未连接」:进入 25 秒暖机期,期间状态保持「检测中」,
238
+ 连上即变「已连接」;暖机结束后仍未连上才显示「未连接」。
239
+ - 「检测中」期间多一行小字:「正在启动语音服务,已等待 N 秒(模型加载通常要 10–30 秒)」,
240
+ 每秒刷新,让人知道程序在做事。
241
+
242
+ ## [0.12.5] - 2026-10-28
243
+
244
+ ### 变更
245
+
246
+ - 头像弹窗里删掉「在这里写 ID;要换图时再点下面的按钮」这句提示:界面上元素变多之后,
247
+ 它和 ID 输入框已经隔得很远,反而显得多余。
248
+
249
+ ## [0.12.4] - 2026-10-28
250
+
251
+ ### 新增
252
+
253
+ - 系统语音那一行加了「共 N 个音色」和「刷新列表」:Electron 里音色列表有时加载得晚,
254
+ 刷新一下就能重新枚举,也方便判断到底是系统里没有还是浏览器没给。
255
+
256
+ ## [0.12.3] - 2026-10-28
257
+
258
+ ### 修复
259
+
260
+ - 点开头像 / 插件详情 / 设置页会卡死:新加的音色列表在**渲染期间**写 store,
261
+ 而 store 变更又触发重渲染,形成无限循环。现在渲染路径只读不写,音色列表做内容去重,
262
+ 并且只向浏览器询问一次(异步就绪后由 `voiceschanged` 事件刷新)。
263
+
264
+ ## [0.12.2] - 2026-10-28
265
+
266
+ ### 修复
267
+
268
+ - 系统语音只挑中文音色,英文用户听到的是中文音色念英文。改为**按待读文本的语言**挑:
269
+ 回复里有汉字用中文音色,否则用英文音色;手动选过的音色优先。
270
+ - 音色列表同时列出中英两种,按界面语言排序;试听句跟随插件界面语言。
271
+
272
+ ## [0.12.1] - 2026-10-28
273
+
274
+ ### 修复
275
+
276
+ - 头像弹窗里新加的「系统语音」素材放不下,标签被下拉框盖住:改成「标签 + 试听」一行、
277
+ 下拉框独占一行,弹窗宽度 368px → 420px。
278
+
279
+ ### 文档
280
+
281
+ - README 增加「系统语音怎么更好听」:Win10 只有老 SAPI 音色;Win11 可安装自然音色包,
282
+ 装好后重启 DSH 即可在列表里选到(中英各一份)。
283
+
284
+ ## [0.12.0] - 2026-10-28
285
+
286
+ ### 新增
287
+
288
+ - **系统语音可选**:音色选「系统语音」时多一行下拉框,列出浏览器提供的所有中文音色
289
+ (自动排序:神经网络音色优先,老的 SAPI 音色靠后),旁边带「试听」。选择存本机。
290
+ - 系统语音的语速现在跟随设置里的语速(之前固定 0.95)。
291
+
292
+ ## [0.11.11] - 2026-10-28
293
+
294
+ ### 变更
295
+
296
+ - 服务地址下的提示语改成更直接的说法:「想用本地语音服务请在本机配置(模型和参考音频自备)。」
297
+
298
+ ## [0.11.10] - 2026-10-28
299
+
300
+ ### 修复
301
+
302
+ - 文案跟实际行为对齐:服务离线时的重试早已改成 2.5 秒,提示语里还写着 8 秒。
303
+
304
+ ## [0.11.9] - 2026-10-28
305
+
306
+ ### 变更
307
+
308
+ - 音色选「系统语音」时,**语音服务**区块(服务进程 / 启动配置 / 随 DSH 启动 / 诊断里的服务行)
309
+ 在设置页和插件详情页都自动隐藏;只有进程仍在运行、或开着自启时才保留(给一个停止入口)。
310
+ - 「随 DSH 启动」改名为「**DSH 启动时拉起语音服务**」,说明白是拉服务、不是插件。
311
+ - 去掉「语音服务 / 语音服务进程」两个重复的标题。
312
+
313
+ ## [0.11.8] - 2026-10-27
314
+
315
+ ### 修复
316
+
317
+ - 服务状态探测的「离线后重试」从来没有真正生效:调度函数总是以 `attempt=0` 重启探测,
318
+ 于是一直每 700ms 轮询、永远进不了 offline 状态(也就看不到「未连接」)。
319
+ 现在:瞬时失败重试一次(700ms)→ 判离线 → 每 **2.5 秒**重试(原来名义上是 8 秒);
320
+ 连上后改为每 **30 秒**静默保活,服务中途挂掉也能自己变红。
321
+
322
+ ## [0.11.7] - 2026-10-26
323
+
324
+ ### 新增
325
+
326
+ - `assets/icon-180.png`:市场卡片图标(由 `icon.svg` 渲染,180×180 位图)。
327
+ - `screenshots.json`:声明 7 张截图,插件市场详情页按此顺序展示。
328
+
5
329
  ## [0.11.6] - 2026-10-25
6
330
 
7
331
  ### 变更
package/README.md CHANGED
@@ -24,11 +24,13 @@
24
24
  **朗读**
25
25
 
26
26
  - 点 ID 右侧的小喇叭,朗读这一条回复的正文(只读最终回答,不读思考过程和折叠的工具步骤);
27
- - 两种引擎:系统语音(开箱即用)或你自己的本地服务;
28
- - 播放控制条:朗读时接在小喇叭右侧,可暂停/继续、上一句/下一句、五档语速(0.95× / 1.00× / 1.05× / 1.10× / 1.15×)、停止;
27
+ - 可打开「自动朗读新回复」,新一轮回答结束后自动念(历史轮次不会补念);
28
+ - 两种引擎:系统语音(开箱即用,**可选音色**,按回复语言自动选中/英文音色、优先神经网络音色)或你自己的本地服务;
29
+ - 播放控制条:朗读时接在小喇叭右侧,可暂停/继续、上一句/下一句、五档语速(0.95× / 1.00× / 1.05× / 1.10× / 1.15×)、停止——**两种引擎都支持**;
30
+ - 音量滑块(0–100%,**默认 50%**);
29
31
  - 语气三档:平稳 / 自然 / 活泼,随请求发给你的服务;
30
- - 试听:不用回到聊天,在设置里直接试一句;
31
- - 失败提示:某句合成失败时,小喇叭旁出现红点,悬停可看原因;
32
+ - 试听:选「本地服务」时,设置页 / 插件详情页 / 头像弹窗里都有「试听一句」;选「系统语音」时,音色选择那一行自带试听;
33
+ - 失败提示:某句合成失败时,小喇叭旁出现红点,悬停可看原因;试听失败时按钮旁会直接显示简短原因;
32
34
  - 长回复按句切分、提前两段预生成,句间不卡顿。
33
35
 
34
36
  ![朗读时小喇叭右侧的控制条](docs/images/bar.png)
@@ -36,7 +38,8 @@
36
38
  **其他**
37
39
 
38
40
  - 设置 → **角色头像**:头像、ID、字号、预设、朗读、引擎、语气、语速、服务地址、试听、诊断都在这页;
39
- - **语音服务进程**:一键启动/停止你自己配置的服务进程,可勾选「随 DSH 启动」(设置页与插件详情页都能操作);
41
+ - **语音服务进程**:一键启动 / 停止 / **重启**你自己配置的服务进程,可勾选「DSH 启动时拉起语音服务」(设置页与插件详情页内容完全一致);切到「系统语音」时整块自动隐藏,进程仍在跑或开着自启时例外;
42
+ - **状态跟着过程走**:点启动后先显示「检测中 · 已等待 N 秒(模型加载通常 10–30 秒)」,连上即变「已连接」;超过 25 秒仍未连上才显示「未连接」,并给出简短原因(超时 / 连不上 / 服务返回 HTTP 码);
40
43
  - 诊断信息:服务状态与模型名、上一句合成耗时、播放进度、最近一次错误;
41
44
  - **界面语言可切换**:中文 / English 两个按钮,放在插件详情页、设置 → 角色头像、点头像弹出的面板三处;选择只记在本机,刷新/重启后保持;
42
45
  - 所有数据只在本机 `localStorage`,不上传、不联网(除非你把服务地址指向远程)。
@@ -70,7 +73,17 @@
70
73
 
71
74
  插件本身**不下载模型、不附带参考音频、不启动任何服务**。它只做两件事:用系统语音读,或者调用你给的 HTTP 服务。
72
75
 
73
- 默认地址 `http://127.0.0.1:8123`,可在面板、插件详情页或设置页修改,旁边会显示「已连接 / 未连接」的实时状态。服务不可用时会自动退回系统语音,状态点**每 8 秒自动重试一次**,起好服务后不用刷新。
76
+ 默认地址 `http://127.0.0.1:8123`,可在面板、插件详情页或设置页修改,旁边会显示「已连接 / 未连接」的实时状态。服务不可用时会自动退回系统语音;状态点在离线时**每 2.5 秒重试一次**,连上后每 30 秒静默保活一次,中途挂掉也会自己变红。
77
+
78
+ ### 系统语音怎么更好听
79
+
80
+ 「系统语音」用的是**浏览器能看到的系统音色**,列表由系统和你用的客户端决定:
81
+
82
+ - **Windows 10**:基本只有老的 SAPI 音色(如「慧慧」),机械感明显,这是系统本身的限制;
83
+ - **Windows 11**:可以安装微软的**自然音色**(晓晓、云希等)。路径是 设置 → 时间和语言 → 语音 → 添加语音(部分版本在「讲述人」里有自然语音的下载项)。装好后**重启一次 DSH**,音色下拉框里会出现名字带 `Natural` 的项;
84
+ - 下拉框会**自动把自然音色排在最前**,不用手动找。
85
+
86
+ 如果下拉框里只有老音色,说明系统里没有、或者当前客户端拿不到——这时候更实际的办法是用「本地服务」:要么跑下面那个示例(微软在线音色),要么接你自己训练的模型。
74
87
 
75
88
  **先用一个示例跑通**:仓库里带了一个最小实现,用微软 Edge 的在线语音:
76
89
 
@@ -84,7 +97,7 @@ python examples/simple_tts.py # 监听 127.0.0.1:8123
84
97
  **一键启动服务(可选)**:插件的宿主端可以替你启动那个进程,入口两处——**设置 → 角色头像 → 语音服务**,以及**插件详情页**的同名区块。
85
98
 
86
99
  - 「启动服务 / 停止服务」:执行你填的那条命令;
87
- - 「随 DSH 启动」:DSH 启动时自动把它拉起来(不是开机自启);
100
+ - 「DSH 启动时拉起语音服务」:DSH 启动时自动把它拉起来(不是开机自启);
88
101
  - 「启动配置」里填:**启动命令**、**工作目录**、**环境变量**(每行 `KEY=VALUE`)。
89
102
 
90
103
  ```
@@ -98,7 +111,7 @@ python examples/simple_tts.py # 监听 127.0.0.1:8123
98
111
  几点要说清楚:
99
112
 
100
113
  - 命令是**你自己填的**,插件不附带任何服务;它只是替你执行、托管这个子进程;
101
- - 进程生命周期跟随 DSH:DSH 退出时它会被一起收掉;「随 DSH 启动」只在 DSH 启动时执行一次;
114
+ - 进程生命周期跟随 DSH:DSH 退出时它会被一起收掉;「DSH 启动时拉起语音服务」只在 DSH 启动时执行一次;
102
115
  - 端口上已经有服务在跑时(比如你手动开的),插件会显示「端口上已有服务(非本插件启动)」,不会重复启动;
103
116
  - 宿主端代码在 DSH 启动时加载,**安装或升级插件后要重启一次 DSH**,这一块才可用;界面会提示「宿主端未加载」。
104
117
 
@@ -115,6 +128,8 @@ POST /tts
115
128
 
116
129
  需要允许 CORS(`Access-Control-Allow-Origin: *` 并响应 `OPTIONS` 预检)。`tone` 是建议值,不认识就忽略;`speed` 范围 0.7–1.3。
117
130
 
131
+ **试听没声音时**:插件会先直连你填的地址,1.5 秒内没有响应就自动改由 DSH 宿主进程转发(日志在 `~/.dsh/storages/dsh-avatar-frame/debug.log`)。设置页的试听按钮旁会显示「试听中 n/m」或失败原因。
132
+
118
133
  **启动失败时先看这一条**:设置页「启动配置」下面会显示进程退出前的输出。如果看到
119
134
 
120
135
  ```
@@ -200,14 +215,15 @@ PermissionError: [WinError 10013] 以一种访问权限不允许的方式做了
200
215
  - Two engines: the system voice, or your own local service;
201
216
  - Playback bar beside the speaker: pause/resume, previous/next sentence, five speeds (0.95×–1.15×), stop;
202
217
  - Three tone presets (calm / natural / lively) sent to your service;
203
- - Preview the voice from the settings page without touching the chat;
204
- - Failure dot next to the speaker with the reason on hover;
218
+ - Preview: with 'Local service' there is a preview button on the settings page, the plugin page and the avatar panel; with 'System voice' the voice picker has its own preview;
219
+ - Failure dot next to the speaker with the reason on hover; a failed preview shows a short reason next to the button;
205
220
  - Long replies are split by sentence and pre-generated two chunks ahead, so playback stays continuous.
206
221
 
207
222
  **The rest**
208
223
 
209
224
  - Settings → **Character avatar** holds everything: avatar, ID, size, presets, read-aloud, engine, tone, speed, endpoint, preview, diagnostics;
210
- - **Service process**: start/stop your own TTS process and optionally start it with DSH (available on both the settings page and the plugin page);
225
+ - **Service process**: start / stop / **restart** your own TTS process, optionally started with DSH; the settings page and the plugin page show exactly the same block;
226
+ - **Status that follows the launch**: after clicking start you see "checking · N s elapsed (model loading usually takes 10–30s)", then "connected"; only after 25s without a connection does it say "not connected" with a short reason (timeout / unreachable / HTTP code);
211
227
  - Diagnostics: service state and model name, last synthesis time, playback progress, last error;
212
228
  - **Chinese / English UI switch** on the plugin page, the settings page and the avatar popup; the choice is stored locally;
213
229
  - Everything is kept in this browser's `localStorage`; nothing is uploaded unless you point the endpoint at a remote host.
@@ -239,7 +255,17 @@ The package is published on npm as [`dsh-avatar-frame`](https://www.npmjs.com/pa
239
255
 
240
256
  ### Speech service
241
257
 
242
- The plugin never downloads a model or bundles a voice. It either uses the system voice or calls an HTTP service you provide. The default address is `http://127.0.0.1:8123` and can be changed in the panel, the plugin page or the settings page; a status dot shows connected / not connected and **retries every 8 seconds**, so start the service and watch it turn green — no refresh needed.
258
+ The plugin never downloads a model or bundles a voice. It either uses the system voice or calls an HTTP service you provide. The default address is `http://127.0.0.1:8123` and can be changed in the panel, the plugin page or the settings page; a status dot shows connected / not connected and **retries every 2.5 seconds**, so start the service and watch it turn green — no refresh needed.
259
+
260
+ ### Making the system voice sound better
261
+
262
+ The **System voice** option lists the voices your system exposes to the browser:
263
+
264
+ - **Windows 10**: usually only the legacy SAPI voices (e.g. Huihui), which sound robotic — that is a system limit, not the plugin;
265
+ - **Windows 11**: you can install Microsoft's **natural voices** (Xiaoxiao, Yunxi, …) from Settings → Time & language → Speech → Add voices (some builds also offer natural voices under Narrator). After installing, **restart DSH** and the picker will list entries containing `Natural`;
266
+ - The picker **sorts natural voices first** automatically.
267
+
268
+ If only legacy voices show up, the more practical route is **Local service**: run the example below (Microsoft online voices) or point the plugin at your own model.
243
269
 
244
270
  **Try it with the bundled example** (Microsoft Edge online voices):
245
271
 
@@ -253,7 +279,7 @@ Point the plugin at `http://127.0.0.1:8123` and click the speaker. To use your o
253
279
  **One-click service start (optional).** The host half can launch the process for you; the same block exists in **Settings → Character avatar → Speech service** and on the plugin page:
254
280
 
255
281
  - Start / Stop service — runs the command you configure;
256
- - Start with DSH — launches it once at DSH startup (not an OS autostart);
282
+ - Start the speech service with DSH — launches it once at DSH startup (not an OS autostart);
257
283
  - Launch settings — the command, the working directory, and `KEY=VALUE` environment lines.
258
284
 
259
285
  The command is yours: the plugin does not ship a service, it only executes and supervises that child process. Its lifetime follows DSH, and if something is already listening the plugin says so instead of starting a second copy.