Pregunta

Lo siguiente es la forma de hacer que PowerShell hablara.

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

En realidad me gustaría hacer de lo contrario. Si hablo, ¿puede PowerShell convertirlo en letras?

Si digo en mi grabadora de sonido "Hola, puedo hablar", ¿se convertirá en texto?

Si es posible, por favor, guíame ¿Cómo lograrlo?

¿Fue útil?

Solución

Parece que puedes con System.Speech.Recognition. Aquí hay incluso ejemplo de uso escrito en PowerShell:

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

Este enlace fue 404, así que lo excavé de la máquina de atrás.

Controle su PC con su voz ... y PowerShell

Por Joel 'Jaykul' Bennett el 25 de junio de 2009

¿Alguna vez ha querido poder hacer preguntas a su computadora y hacer que le responda en voz alta? ¿Alguna vez se ha preguntado si su computadora podría ser más como las que ejecutan Star Trek Enterprise, respondiendo a consultas y comandos de voz? ¿Has jugado con Zwave o X10 Home Automation y pensaste que el control de voz de tus dispositivos sería un próximo paso obvio?

Bueno, está bien ... no te voy a mostrar cómo encender las luces o trabajar con la automatización del hogar, pero eso es lo principal que me mantiene pensando en estas cosas de reconocimiento de voz. ¿Qué geek no quiere entrar a la sala de estar y decir "computadora: luces encendidas" y hacer que funcione?

En cambio, como primer paso para todo eso, permítanme mostrarle cómo usar PowerShell para hacer scripts simples de reconocimiento de comandos de voz ... ¡que pueden disparar cualquier script de PowerShell que le importa escribir! El código que sigue es realmente un módulo, aunque solo puede obtenerlo como un script, y realmente requiere PowerShell 2.0 para los eventos, aunque sería trivial refactorizarlo para trabajar en PowerShell 1.0 utilizando la biblioteca de Pseventing de Oisin.

$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

Básicamente, hay solo una función de la que debes preocuparte aquí: New-VoiceCommands. Pasas un hashtable que mapea las cuerdas a los bloques de scriptsClocks, y si usas elwlistenswitch, eso es todo lo que hay. También puede llamar a la lista de asistencia manualmente y, por supuesto, he proporcionado la función, por ejemplo, para que sea más fácil que la computadora hable ...

Una vez que la computadora está "escuchando" ... solo dices que es nombre, seguido de uno de tus comandos. Me gusta eso porque asegura que no ejecute los scripts por accidente, pero puedes eliminar el ${Env:ComputerName}, cadena desde el comienzo del grammarbuilder si crees que no es necesario, o puedes codificarlo a algo más que el nombre de tu computadora, como decir "Hal, por favor, te lo ruego ..." o "computadora, por favor" o lo que sea ?

Puedes hacer muchas cosas con esto ... cualquier cosa, realmente ... pero para darte un ejemplo que puedes entender fácilmente, voy a hacer algo muy simple y hacer que mi computadora solo responda algunas preguntas básicas. Al responderme y luego agregar algunos comandos para que inicie una aplicación o una página web.

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" }
}

¿Ves lo fácil que es eso? Puede usar "decir" para hablar cualquier texto (aunque en algún momento obtendrá mejores resultados que otros), y puede invocar cualquier otro comando de PowerShell, incluidos los comandos HTTPrest para obtener datos web o comandos de WASP para la automatización de Windows, o los comandos PowerBoots para mostrar Salida en texto grande, o cmdlets para controlar los dispositivos X10 o Zwave ... ¿Sabes, algo?

Otros consejos

El reconocimiento de voz sigue siendo una tecnología experimental. Hay algunos .net Framework recursos, incluso con un ejemplo. Sin embargo, no espere crear un PowerShiri en el corto plazo.

La tecnología es un poco más allá de "experimental", pero está lejos de ser confiable.

Exchange hace esto ahora con la opción "Vista previa de correo de voz" de UM. Los resultados pueden variar de bastante bueno a hilarante, dependiendo del altavoz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top