windows - 如何更改用于 SAPI.SPVoice 的语音

标签 windows powershell windows-10 sapi

我希望能够为我的 Text-To-Speech 输出选择另一种语音。
我正在使用 ComObject SAPI.SPVoice 但我发现我无法更改实际使用的语音。
(顺便说一句 - 我使用 SAPI.SPVoice 因为它适用于 Windows 10 上的 PowerShell Core 和 PowerShell Desktop)

${PromptTTS} = New-Object -ComObject SAPI.SPVoice
❯ $PromptTTS | gm
   TypeName: System.__ComObject#{269316d8-57bd-11d2-9eee-00c04f797396}

Name                                   MemberType   Definition
----                                   ----------   ----------
DisplayUI                              Method       void DisplayUI (int hWndParent, string Title, string TypeOfUI, Variant ExtraData)
GetAudioOutputs                        Method       ISpeechObjectTokens GetAudioOutputs (string RequiredAttributes, string OptionalAttributes)
GetVoices                              Method       ISpeechObjectTokens GetVoices (string RequiredAttributes, string OptionalAttributes)
IsUISupported                          Method       bool IsUISupported (string TypeOfUI, Variant ExtraData)
Pause                                  Method       void Pause ()
Resume                                 Method       void Resume ()
Skip                                   Method       int Skip (string Type, int NumItems)
Speak                                  Method       int Speak (string Text, SpeechVoiceSpeakFlags Flags)
SpeakCompleteEvent                     Method       int SpeakCompleteEvent ()
SpeakStream                            Method       int SpeakStream (ISpeechBaseStream Stream, SpeechVoiceSpeakFlags Flags)
WaitUntilDone                          Method       bool WaitUntilDone (int msTimeout)
AlertBoundary                          Property     SpeechVoiceEvents AlertBoundary () {get} {set}
AllowAudioOutputFormatChangesOnNextSet Property     bool AllowAudioOutputFormatChangesOnNextSet () {get} {set}
AudioOutput                            Property     ISpeechObjectToken AudioOutput () {get} {set by ref}
AudioOutputStream                      Property     ISpeechBaseStream AudioOutputStream () {get} {set by ref}
EventInterests                         Property     SpeechVoiceEvents EventInterests () {get} {set}
Priority                               Property     SpeechVoicePriority Priority () {get} {set}
Rate                                   Property     int Rate () {get} {set}
Status                                 Property     ISpeechVoiceStatus Status () {get}
SynchronousSpeakTimeout                Property     int SynchronousSpeakTimeout () {get} {set}
Voice                                  Property     ISpeechObjectToken Voice () {get} {set by ref}
Volume                                 Property     int Volume () {get} {set}
queryMSDNClassInfo                     ScriptMethod System.Object queryMSDNClassInfo();

我的研究表明我应该能够:
❯ $PromptTTS.Voice = ${PromptTTS}.GetVoices().Item(0) ; $PromptTTS.Speak("Hello voice 0")
❯ $PromptTTS.Voice = ${PromptTTS}.GetVoices().Item(1) ; $PromptTTS.Speak("Hello voice 1")
❯ $PromptTTS.Voice = ${PromptTTS}.GetVoices().Item(2) ; $PromptTTS.Speak("Hello voice 2")

等等。

然而,虽然命令执行没有错误,使用的声音/听到的不会改变。

最佳答案

不幸的是,分配给 .Voice从 v7.1.0-preview.2 开始,在 PowerShell Core 中无法更改说话声音。 - 它仅适用于 Windows PowerShell(PowerShell 版本最高为 v5.1)。

.NET Core 的 COM 支持是有限的,虽然 PowerShell (Core) 部分弥补了这一点,但有些东西仍然不起作用。

实际上,PowerShell (Core) 6+ 中悄悄地忽略了以下分配:

# !! IGNORED in PowerShell [Core] 6+ - the default voice (David)
# !! is NOT changed (to Hedda).
$PromptTTS.Voice = $PromptTTS.GetVoices().Item(1)

就个人而言,我不知道解决方法(至少仅使用 PowerShell 代码)。

技术背景 :

检查 .Voice$PromptTTS | Get-Member Voice 的属性(property)产量:

   TypeName: System.__ComObject#{269316d8-57bd-11d2-9eee-00c04f797396}

Name  MemberType Definition                                    
----  ---------- ----------                                    
Voice Property   ISpeechObjectToken Voice () {get} {set by ref}

我怀疑 set by ref部分是问题,可能与下面的问题有关,引用from this GitHub issue :

the ComBinder is not supported in .NET Core (the call ComInterop.ComBinder.TryBindSetMember in PowerShell Core is a stub method).

关于windows - 如何更改用于 SAPI.SPVoice 的语音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61442080/

相关文章:

windows - EC2 Windows 实例重启后不从启动文件夹启动批处理文件

python - 如何在 Apache 下使用 Python 3.0?

sql-server - SQL Server Powershell错误:在此计算机上找不到Invoke-SqlCmd命令

internet-explorer - Windows 10 中的 TWebbrowser : Microsoft Edge (formerly Spartan)/Internet Explorer legacy issues

windows - 找不到类 org.apache.hadoop.fs.s3native.NativeS3FileSystem (Spark 1.6 Windows)

windows - 用于查看可执行镜像加载了哪些文件/dll 的实用程序

forms - PowerShell 表单。如果我无法调用函数或使用 Write-output,但在我的 Form Closing 事件中,如果我使用 Write-Host,它会起作用

powershell - 使用 Azure Powershell 或 xpat cli 如何将我的网站连接到 github Hook

vbscript - 以编程方式创建 Edge 浏览器实例

c++ - Visual C++ 2010 Express 中的新 ATL COM 项目 : Missing Template