Powershell可以说话,但如果我说话,它可以写吗?

时间:2012-02-20 13:04:15

标签: powershell powershell-v2.0 speech-recognition speech-to-text

以下是让PowerShell发言的方法。

Add-Type -AssemblyName System.Speech
$synthesizer = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$synthesizer.Speak('Hey, I can speak!')

其实我想反对。如果我说话,可以将powershell转换成字母。

如果我在我的录音机中说“嘿,我可以说”,它会转换成文字吗?

如果可能请指导我如何实现它?

3 个答案:

答案 0 :(得分:10)

您可以使用System.Speech.Recognition。这里甚至是用PowerShell编写的示例用法:

http://huddledmasses.org/control-your-pc-with-your-voice-and-powershell/

这个链接是404,所以我把它挖出机器。

用你的声音控制你的电脑......和PowerShell

Joel'Jaykul'Bennett于2009年6月25日

你有没有想过能够问你的计算机问题并让它大声回答你?你有没有想过你的计算机是否更像是运行星际迷航企业的计算机,响应语音查询和命令?您是否使用过ZWave或X10家庭自动化,并认为您的设备的语音控制将是明显的下一步?

好吧,好吧......我不会告诉你如何打开灯或使用家庭自动化 - 但这是让我思考这种语音识别的主要因素。什么极客不想走进起居室并说“电脑:灯亮”并让它发挥作用?

相反,作为所有这一切的第一步,让我向您展示如何使用PowerShell执行简单的语音命令识别脚本...这可以触发您需要编写的任何PowerShell脚本!下面的代码实际上是一个模块,虽然你可以将它作为脚本点源,并且它确实需要PowerShell 2.0用于事件,尽管使用Oisin的PSEventing库重构它以使用PowerShell 1.0是微不足道的。 / p>

$null = [Reflection.Assembly]::LoadWithPartialName("System.Speech")

## Create the two main objects we need for speech recognition and synthesis
if (!$global:SpeechModuleListener) {
    ## For XP's sake, don't create them twice...
    $global:SpeechModuleSpeaker = New-Object System.Speech.Synthesis.SpeechSynthesizer
    $global:SpeechModuleListener = New-Object System.Speech.Recognition.SpeechRecognizer
}

$script:SpeechModuleMacros = @{}
## Add a way to turn it off
$script:SpeechModuleMacros.Add("Stop Listening", {$script:listen = $false; Suspend-Listening})
$script:SpeechModuleComputerName = ${env:ComputerName}

function Update-SpeechCommands {
    #.Synopsis 
    #  Recreate the speech recognition grammar
    #.Description
    #  This parses out the speech module macros, 
    #  and recreates the speech recognition grammar and semantic results, 
    #  and then updates the SpeechRecognizer with the new grammar, 
    #  and makes sure that the ObjectEvent is registered.
    $choices = New-Object System.Speech.Recognition.Choices
    foreach ($choice in $script:SpeechModuleMacros.GetEnumerator()) {
        New-Object System.Speech.Recognition.SemanticResultValue $choice.Key, $choice.Value.ToString() |
            ForEach-Object { $choices.Add($_.ToGrammarBuilder()) }
    }

    if ($VerbosePreference -ne "SilentlyContinue") {
        $script:SpeechModuleMacros.Keys |
            ForEach-Object { Write-Host"$Computer, $_" -Fore Cyan }
    }

    $builder = New-Object System.Speech.Recognition.GrammarBuilder"$Computer, "
    $builder.Append((New-ObjectSystem.Speech.Recognition.SemanticResultKey"Commands", $choices.ToGrammarBuilder()))
    $grammar = New-Object System.Speech.Recognition.Grammar $builder
    $grammar.Name = "Power VoiceMacros"

    ## Take note of the events, but only once (make sure to remove the old one)
    Unregister-Event"SpeechModuleCommandRecognized" -ErrorAction SilentlyContinue
    $null = Register-ObjectEvent $grammar SpeechRecognized `
                -SourceIdentifier"SpeechModuleCommandRecognized" `
                -Action {iex $event.SourceEventArgs.Result.Semantics.Item("Commands").Value}

    $global:SpeechModuleListener.UnloadAllGrammars()
    $global:SpeechModuleListener.LoadGrammarAsync($grammar)
}

function Add-SpeechCommands {
    #.Synopsis
    #  Add one or more commands to the speech-recognition macros, and update the recognition
    #.Parameter CommandText
    #  The string key for the command to remove
    [CmdletBinding()]
    Param([hashtable]$VoiceMacros,[string]$Computer=$Script:SpeechModuleComputerName)

    ## Add the new macros
    $script:SpeechModuleMacros += $VoiceMacros 
    ## Update the default if they change it, so they only have to do that once.
    $script:SpeechModuleComputerName = $Computer 
    Update-SpeechCommands
}

function Remove-SpeechCommands {
    #.Synopsis
    #  Remove one or more command from the speech-recognition macros, and update the recognition
    #.Parameter CommandText
    #  The string key for the command to remove
    Param([string[]]$CommandText)
    foreach ($command in $CommandText) {
        $script:SpeechModuleMacros.Remove($Command)
    }
    Update-SpeechCommands
}

function Clear-SpeechCommands {
    #.Synopsis
    #  Removes all commands from the speech-recognition macros, and update the recognition
    #.Parameter CommandText
    #  The string key for the command to remove
    $script:SpeechModuleMacros = @{}
    ## Default value: A way to turn it off
    $script:SpeechModuleMacros.Add("Stop Listening", {Suspend-Listening})
    Update-SpeechCommands
}

function Start-Listening {
    #.Synopsis
    #  Sets the SpeechRecognizer to Enabled
    $global:SpeechModuleListener.Enabled = $true
    Say "Speech Macros are $($Global:SpeechModuleListener.State)"
    Write-Host "Speech Macros are $($Global:SpeechModuleListener.State)"
}

function Suspend-Listening {
    #.Synopsis
    #  Sets the SpeechRecognizer to Disabled
    $global:SpeechModuleListener.Enabled = $false
    Say "Speech Macros are disabled"
    Write-Host "Speech Macros are disabled"
}

function Out-Speech {
    #.Synopsis
    #  Speaks the input object
    #.Description
    #  Uses the default SpeechSynthesizer settings to speak the string representation of the InputObject
    #.Parameter InputObject
    #  The object to speak 
    #  NOTE: this should almost always be a pre-formatted string,
    #        most objects don't render to very speakable text.
    Param([Parameter(ValueFromPipeline=$true)][Alias("IO")]$InputObject)
    $null = $global:SpeechModuleSpeaker.SpeakAsync(($InputObject | Out-String))
}

function Remove-SpeechXP {
    #.Synopis
    #  Dispose of the SpeechModuleListener and SpeechModuleSpeaker
    $global:SpeechModuleListener.Dispose(); $global:SpeechModuleListener = $null
    $global:SpeechModuleSpeaker.Dispose();  $global:SpeechModuleSpeaker = $null
}

Set-Alias asc Add-SpeechCommands
Set-Alias rsc Remove-SpeechCommands
Set-Alias csc Clear-SpeechCommands
Set-Alias say Out-Speech
Set-Alias listen Start-Listener
Export-ModuleMember -Function * -Alias * -VariableSpeechModuleListener, SpeechModuleSpeaker

这里基本上只需要担心一个功能:New-VoiceCommands。你传递一个哈希表,它将字符串映射到scriptblocks,如果你使用-Listenswitch就可以了。你也可以手动调用Start-Listening,当然,我已经提供了Say功能,让计算机更容易说话...

一旦计算机“聆听”......你只需说出它的名字,然后是你的一个命令。我喜欢这样,因为它确保我不会意外地运行脚本,但如果您认为没有必要,可以从GrammarBuilder的开头删除${Env:ComputerName},字符串,或者您可以将其硬编码到其他内容比你电脑的名字,比如说“哈尔,拜托,求求你......”或“电脑,请”或其他什么?

你可以做很多事情......真的......真的......但是为了给你一个你可以很容易理解的例子,我会做一些非常简单的事情,让我的电脑回答一下通过回复给我几个基本问​​题,然后添加一些命令让它启动应用程序或网页。

Add-SpeechCommands @{
   "What time is it?" = { Say "It is $(Get-Date -f "h:mm tt")" }
   "What day is it?"  = { Say $(Get-Date -f "dddd, MMMM dd") }
   "What's running?"  = {
      $proc = ps | sort ws -desc
      Say $("$($proc.Count) processes, including $($proc[0].name), which is using " +
            "$([int]($proc[0].ws/1mb)) megabytes of memory")
   }
} -Computer "Laptop" -Verbose 

Add-SpeechCommands @{
    "Run Notepad"= { & "C:\Programs\DevTools\Notepad++\notepad++.exe"}
}
Add-SpeechCommands @{
    "Check Gee Mail" = { Start-Process"https://mail.google.com" }
}

你觉得这有多容易吗?您可以使用“Say”来说出任何文本(尽管某些文本将获得比其他文本更好的结果),并且您可以调用任何其他powershell命令,包括用于获取Web数据的HttpRest命令,或用于Windows自动化的WASP命令,或者要显示的PowerBoots命令输出大文本或cmdlet来控制X10或ZWave设备......你知道吗?

答案 1 :(得分:2)

语音识别仍是一项实验性技术。有一些.Net框架resources,即使有example。不过,不要指望很快创建一个PowerShiri。

答案 2 :(得分:1)

这项技术有点过去“实验性”,但它远非可靠。

Exchange现在使用UM的“语音邮件预览”选项执行此操作。根据演讲者的不同,结果可能会有很好的变化,也可能很有趣。