gexgd0419 / NaturalVoiceSAPIAdapter

Make Azure natural TTS voices accessible to any SAPI 5-compatible application.
MIT License
141 stars 6 forks source link

请问如何显示在系统的TTS设置中? #5

Closed Leroy-X closed 4 months ago

Leroy-X commented 4 months ago

image

已正确安装,可以在Balabolka中选择运行。 请问可以显示在系统设置中吗。一些阅读软件好像是直接调用的系统朗读。只能使用系统所选的默认引擎。

非常感谢如此强大的项目!!!

gexgd0419 commented 4 months ago

Windows 里包含的语音系统不止一个,SAPI 5 只是其中一个。

打开 控制面板 > 语音 (Windows XP),或 控制面板 > 语音识别 > 文本到语音转换 (Windows Vista 及以后),看到的语音才是 SAPI 5 语音。注意不是新的系统设置,而是旧的控制面板。

语音属性、文本到语音转换页面截图

SAPI 5 系统从 Windows XP 时代就开始内置在系统中了,并且它有较好的可扩展性,可以安装第三方制作的语音 TTS 引擎。我的这个程序就是参考微软的 SAPI 5 开发者文档 制作的。

而新的系统设置里 时间和语言 > 语音 中提供的语音列表,则是来自另一套语音系统,我称之为 OneCore 语音。这个语音系统是 Win 8 开始向移动端应用提供的,后来也出现在了桌面端的 Win 10/11 中,用于向 Metro/UWP 应用提供语音功能。

对于 UWP 应用而言,OneCore 语音基本上就是唯一能用的语音系统,因此 UWP 应用一般不支持 SAPI 5 语音。而非 UWP 应用则可以自行选择支持哪个语音系统,只不过不同的语音系统也要编写不同的代码,所以有些应用可能两个都支持,有些可能只支持其中一个。比如,Chromium 系浏览器就不支持 SAPI 5 语音,包括 Chromium Edge,而 Firefox 就支持。(不过话说 Chromium Edge 的支持也没有必要,毕竟这些语音就是从 Edge 来的……)

最后就是自然语音所使用的又一套语音系统了,实际上就是 Azure Speech SDK。这个程序的作用,就是把 SAPI 5 系统的指令翻译成 Azure Speech SDK 使用的指令,加上提取出的讲述人语音的密钥,实现将讲述人语音提供给所有支持 SAPI 5 的 TTS 程序。

我当初也考虑过对接 OneCore 语音系统。可是微软的官方文档里是这么说的:

Only Microsoft-signed voices installed on the system can be used to generate speech.

能够正常使用的 OneCore 语音,必须具有微软的签名!

就凭这一点,支持 OneCore 怕是不可能了,这个本身就“破解”了微软自然语音的项目是不可能拿到微软官方的认证的……

Leroy-X commented 4 months ago

好的,非常感谢。似乎这里选择了默认,第三方应用还是会用之前的机械默认。估计是不支持SAPI5吧。

Only Microsoft-signed voices installed on the system can be used to generate speech. 那这暂时就没办法了哈。

我去下个火狐试试,看看有什么电子书阅读器支持SAPI5吗,我主要用于听书。一直都是用的安卓模拟器+multitts

再次感谢!!!!

Leroy-X commented 4 months ago

@gexgd0419 你好,我找到了这个帖子 还有这个。 开发称可以通过修改注册表来支持SAPI5. 也可以在chrome中使用它。可以帮我看下怎么操作吗,我没有找到语音列表对应的注册表 :(

gexgd0419 commented 4 months ago

系统中已安装的 SAPI 5 语音的注册表信息位于 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens 中。其每一个子键对应着一个语音。

但是本引擎需要根据已安装的讲述人语音来动态生成列表,所以其采用的方式并不是将每一个语音都放在这里,而是注册了一个枚举器 (enumerator),其注册表信息位于 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\TokenEnums\NaturalVoiceEnumerator

SAPI 5 系统每次需要列出语音列表时,就会调用这个枚举器,之后枚举器再根据已安装的讲述人语音、当前可用的 Edge 语音列表等信息,动态生成自己的语音列表,SAPI 5 再将其与 Tokens 中的静态语音列表合并。

与之对应的,OneCore 语音系统的注册表位置是 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens。也就是把 Speech 换成了 Speech_OneCore

有人试验过将 OneCore 语音的注册表复制到 SAPI 5 的注册表,之后确实可以在支持 SAPI 5 语音的程序里使用那些额外的 OneCore 语音。可以用下面的 PowerShell 代码复制注册表信息(要求管理员权限):

Copy-Item HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\ HKLM:\SOFTWARE\Microsoft\Speech\Voices\ -Recurse

系统自带的中文的语音中,SAPI 5 语音只有一个:Microsoft Huihui Desktop,而 OneCore 语音有三个:Microsoft Huihui,Microsoft Kangkang,Microsoft Yaoyao。这样复制注册表后,确实 SAPI 5 语音多出了三项,且也能发声,但是似乎丢失了一些音频参数:Kangkang 和 Yaoyao 听起来完全一样了。Kangkang 本应该是男性语音来着,结果也变成女声了。

这说明 OneCore 的注册表可以复制到 SAPI 5 的注册表中,且仍能运作。

但是反过来,将 SAPI 5 的注册表复制到 OneCore 的注册表呢?这个就不好说了。毕竟按文档的描述,OneCore 是个比 SAPI 5 更封闭的系统,甚至还要求语音具有微软签名。

不过如果你还是有兴趣的话,也不妨试一下复制注册表究竟有没有用。

Copy-Item HKLM:\SOFTWARE\Microsoft\Speech\Voices\TokenEnums\ HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\ -Recurse

目前 Chromium 浏览器只支持 OneCore 语音,这个是相关的问题报告。问题报告的提出时间是2024年1月4日,所以这个改变应该在它之前。而另一篇微软的漏洞报告指出了由于 Chromium 浏览器对接了 SAPI 5,通过构造特定的 XML 发送给 SAPI 系统,就可以触发漏洞,也就是说 Chromium 肯定是支持过 SAPI 5 语音的。

根据漏洞报告中指向 Chromium 代码库的链接,我找到了这项更改的源头:Chromium Code 链接 | GitHub Chromium 镜像链接

这个代码改动是为了让 Chromium 支持新的 OneCore 语音。简单地说,代码改动后,Chromium 的行为变成了这样:

这个实现带来了一些问题。

它本质上是在尝试用 SAPI 5 的框架加载 OneCore 语音,因此会发生和上述复制 OneCore 注册表到 SAPI 5 注册表后相同的问题:参数丢失,致使 Microsoft Kangkang 变成了“女声”。但是,也正因为使用的依然是 SAPI 5 框架,只需要把 SAPI 5 的注册表复制到 OneCore 的位置,Chromium 就能继续正常使用这些 SAPI 5 语音。

那么为什么我们非得复制注册表不可?因为这个代码实现在检查 OneCore 语音列表成功后,就不会理睬 SAPI 5 语音的列表了:它并没有做两个列表的合并!结果是只有在 Win7 这种没有 OneCore 注册表位置的系统上,它才会检查 SAPI 5 原本的语音列表……

可惜这个问题现在并没有被修复。

Leroy-X commented 4 months ago

终于搞定了,非常感谢!!!

不过如果你还是有兴趣的话,也不妨试一下复制注册表究竟有没有用。

Copy-Item HKLM:\SOFTWARE\Microsoft\Speech\Voices\TokenEnums\ HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\ -Recurse

测试了这个,没效果。也可能是我粘贴错了,我复制到 HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens 路径下了。

  • 当需要获取语音列表时,首先,尝试使用 SAPI 5 框架列出 OneCore 注册表位置的语音。如果上一步失败了,再尝试列出 SAPI 5 本来注册表位置的语音。

我做了个大胆的尝试,直接把 HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens 里面的语音全删了,默认就使用SAPI5了, 完美工作。忘了备份,所以上面的复制是否完全有效暂时不能测试了哈。

唯一不足的是chrome里并没有识别到SAPI5的列表。

Leroy-X commented 4 months ago
Copy-Item HKLM:\SOFTWARE\Microsoft\Speech\Voices\TokenEnums\ HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\ -Recurse

刚又测试了这个,完美。非常感谢