Dotnetowa klasa System.Speech.Synthesis.SpeechSynthesizer pozwala uzyskać dostęp do silnika syntezy mowy.
Utworzony z niej obiekt posiada między innymi metodę Speak, za pomocą której komputer może przemówić ludzkim głosem. Do czego to się może przydać? Tak naprawdę, to pojęcia nie mam. Ale hipotetycznie, jeśli ktoś chciałby usłyszeć ostatnie tytuły artykułów z jakiegoś feeda, mógłby napisać:
Add-Type -AssemblyName System.Speech
$mouth = [Speech.Synthesis.SpeechSynthesizer]::new()
Invoke-RestMethod z3s.pl/feed | % {
$mouth.Speak($_.title)
}
Powyższy przykład może zwłaszcza stwarzać problemy przy dłużych tekstach, ponieważ metoda
Speak
działa synchronicznie, a więc nie zwraca sterowania dopóki odtwarzanie mowy się nie zakończy. Słabo. Całe szczęście, możemy użyć asynchronicznej wersji -
SpeakAsync. Zaktualizowany kod mógłby wyglądać jak poniżej:
Add-Type -AssemblyName System.Speech
$mouth = [Speech.Synthesis.SpeechSynthesizer]::new()
Invoke-RestMethod z3s.pl/feed | % {
try {
$speaker = $mouth.SpeakAsync($_.title)
while(!$speaker.IsCompleted) {}
} finally {
$mouth.SpeakAsyncCancelAll()
}
}
zwraca nam natychmiast sterowanie, a żeby sprawdzić czy mowa się zakończyła, czekamy w pustej pętli aż właściwość
zwróconego obiektu zwróci prawdę. Kiedy wciśniemy ^C, zostanie wywołany wyjątek, co z kolei spowoduje natychmiastowe przejście do bloku
, w którym dokonujemy małego sprzątania.
Nie jest to idealne rozwiązanie, ale na pewno lepsze od tego pierwszego. Myślę, że najlepszym rozwiązaniem byłaby obsługa eventów, ale to już troszkę komplikuje cały skrypt. Dla amibtnych, wersję z obsługą eventów zaprezentowałem na konferencji
Jeśli chcesz otrzymywać nowe, mięsiste protipy na maila, a także zostać czasem powiadomiony o wartościowych wydarzeniach - dołącz do subskrybentów.