我希望能够为我的 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 callComInterop.ComBinder.TryBindSetMember
in PowerShell Core is a stub method).
关于windows - 如何更改用于 SAPI.SPVoice 的语音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61442080/