Speech
How to use the speech classes of the bit Butil?
Usage
The speech features are split across two classes. Inject the ones you need and use them like this:
@inject Bit.Butil.SpeechSynthesis speechSynthesis
@inject Bit.Butil.SpeechRecognition speechRecognition
@code {
await speechSynthesis.Speak("Hello from Butil!");
await using var rec = await speechRecognition.Start(options, onResult: r => { /* ... */ });
}SpeechSynthesis
The SpeechSynthesis class wraps the
SpeechSynthesis API
for text-to-speech.
GetVoices:
Returns the list of voices the platform makes available (MDN).
Speak:
Speaks the configured utterance with an optional voice, rate and pitch (MDN).
Pause / Resume / Cancel:
Pauses the current utterance, resumes a paused utterance, or cancels all pending utterances (MDN).
IsSpeaking:
Returns whether the engine is currently speaking (or paused) (MDN).
GetVoices:
Returns the list of voices the platform makes available (MDN).
@inject Bit.Butil.SpeechSynthesis speechSynthesis
<BitButton OnClick="GetVoices">GetVoices</BitButton>
<div>Voices count: @voices.Length</div>
@code {
private SpeechVoice[] voices = [];
private async Task GetVoices()
{
if (await speechSynthesis.IsSupported() is false) return;
voices = await speechSynthesis.GetVoices();
}
}Speak:
Speaks the configured utterance with an optional voice, rate and pitch (MDN).
@inject Bit.Butil.SpeechSynthesis speechSynthesis
<BitTextField @bind-Value="speakText" Label="Text" Multiline Rows="2" />
<select @bind="voiceName">
<option value="">Default voice</option>
@foreach (var voice in voices)
{
<option value="@voice.Name">@voice.Name (@voice.Lang)</option>
}
</select>
<BitButton OnClick="Speak">Speak</BitButton>
@code {
private string? speakText = "Hello from Bit.Butil speech synthesis!";
private string? voiceName;
private async Task Speak()
{
await speechSynthesis.Speak(new SpeechUtterance
{
Text = speakText,
VoiceName = string.IsNullOrWhiteSpace(voiceName) ? null : voiceName,
Rate = 1,
Pitch = 1,
});
}
}Pause / Resume / Cancel:
Pauses the current utterance, resumes a paused utterance, or cancels all pending utterances (MDN).
@inject Bit.Butil.SpeechSynthesis speechSynthesis
<BitButton OnClick="PauseSpeech">Pause</BitButton>
<BitButton OnClick="ResumeSpeech">Resume</BitButton>
<BitButton OnClick="CancelSpeech">Cancel</BitButton>
@code {
private async Task PauseSpeech()
{
await speechSynthesis.Pause();
}
private async Task ResumeSpeech()
{
await speechSynthesis.Resume();
}
private async Task CancelSpeech()
{
await speechSynthesis.Cancel();
}
}IsSpeaking:
Returns whether the engine is currently speaking (or paused) (MDN).
@inject Bit.Butil.SpeechSynthesis speechSynthesis
<BitButton OnClick="IsSpeaking">IsSpeaking</BitButton>
<div>Is speaking: @isSpeaking</div>
@code {
private string? isSpeaking;
private async Task IsSpeaking()
{
isSpeaking = (await speechSynthesis.IsSpeaking()).ToString();
}
}SpeechRecognition
The SpeechRecognition class wraps the
SpeechRecognition API
for speech-to-text (Chromium-based browsers).
Start:
Captures microphone input and reports interim and final transcripts through the onResult callback. The Continuous and InterimResults options control the stream, and onError / onEnd surface errors and completion. Returns an IAsyncDisposable handle that stops recognition when disposed (MDN).
Stop:
Stops the recognition session early. Disposing the handle returned by Start is equivalent (MDN).
Start:
Captures microphone input and reports interim and final transcripts through the onResult callback. The Continuous and InterimResults options control the stream, and onError / onEnd surface errors and completion. Returns an IAsyncDisposable handle that stops recognition when disposed (MDN).
@inject Bit.Butil.SpeechRecognition speechRecognition
<BitButton OnClick="StartRecognition">Start</BitButton>
<div>Transcript: @transcript</div>
@code {
private string? transcript;
private IAsyncDisposable? recognitionHandle;
private async Task StartRecognition()
{
if (await speechRecognition.IsSupported() is false) return;
recognitionHandle = await speechRecognition.Start(
new SpeechRecognitionOptions { Continuous = true, InterimResults = true },
onResult: result =>
{
transcript = result.IsFinal
? $"Final: {result.Transcript} ({result.Confidence:P0})"
: $"Interim: {result.Transcript}";
InvokeAsync(StateHasChanged);
},
onError: err => { InvokeAsync(StateHasChanged); },
onEnd: () => { InvokeAsync(StateHasChanged); });
}
}Stop:
Stops the recognition session early. Disposing the handle returned by Start is equivalent (MDN).
@inject Bit.Butil.SpeechRecognition speechRecognition
<BitButton OnClick="StopRecognition">Stop</BitButton>
@code {
private IAsyncDisposable? recognitionHandle;
private async Task StopRecognition()
{
if (recognitionHandle is null) return;
await recognitionHandle.DisposeAsync();
recognitionHandle = null;
}
}