Skip to content
Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More

Microsoft.Extensions.AI

DownloadsNuGet downloads for Shiny.Speech.MicrosoftAI
Frameworks
.NET
.NET MAUI
Operating Systems
Android
iOS
Windows

Shiny.Speech.MicrosoftAI exposes your Shiny speech providers as standard Microsoft.Extensions.AI interfaces — ISpeechToTextClient and ITextToSpeechClient. This allows any code written against the M.E.AI abstractions to use Shiny’s cloud providers (Azure, ElevenLabs, OpenAI) and platform audio infrastructure.

Register a cloud provider, then add the M.E.AI adapters:

// 1. Register a cloud provider
builder.Services.AddAzureSpeech("subscription-key", "eastus");
// — or —
builder.Services.AddOpenAiSpeech("api-key");
// — or —
builder.Services.AddElevenLabsTextToSpeech("api-key");
// 2. Add M.E.AI adapters
builder.Services.AddShinySpeechClients();

You can also register them individually:

builder.Services.AddShinySpeechToTextClient(); // ISpeechToTextClient only
builder.Services.AddShinyTextToSpeechClient(); // ITextToSpeechClient only

Inject ISpeechToTextClient or ITextToSpeechClient from Microsoft.Extensions.AI:

using Microsoft.Extensions.AI;
public class TranscriptionService(ISpeechToTextClient sttClient, IAudioSource audioSource)
{
async Task<string?> TranscribeFromMic(CancellationToken ct)
{
await using var source = audioSource;
var audioStream = await source.StartCaptureAsync(ct);
var response = await sttClient.GetTextAsync(audioStream, new SpeechToTextOptions
{
SpeechLanguage = "en"
}, ct);
return response.Text;
}
async Task StreamTranscription(Stream audioStream, CancellationToken ct)
{
await foreach (var update in sttClient.GetStreamingTextAsync(audioStream, cancellationToken: ct))
{
switch (update.Kind)
{
case var k when k == SpeechToTextResponseUpdateKind.TextUpdating:
Console.Write($"\r{update.Text}"); // partial result
break;
case var k when k == SpeechToTextResponseUpdateKind.TextUpdated:
Console.WriteLine($"\n{update.Text}"); // final result
break;
}
}
}
}
using Microsoft.Extensions.AI;
public class SpeechService(ITextToSpeechClient ttsClient)
{
async Task Synthesize(CancellationToken ct)
{
var response = await ttsClient.GetAudioAsync(
"Hello from Shiny!",
new TextToSpeechOptions
{
VoiceId = "en-US-AriaNeural",
Speed = 1.0f,
Pitch = 1.0f,
AudioFormat = "audio/mpeg"
},
ct
);
// response.Contents contains DataContent with the audio bytes
}
}

The M.E.AI options are mapped to Shiny options automatically:

M.E.AI PropertyShiny PropertyNotes
SpeechLanguageSpeechRecognitionOptions.CultureISO-639 string → CultureInfo
ModelIdPassed through to response
M.E.AI PropertyShiny PropertyNotes
VoiceIdTextToSpeechOptions.VoiceMapped to VoiceInfo.Id
LanguageTextToSpeechOptions.CultureBCP 47 string → CultureInfo
SpeedTextToSpeechOptions.SpeechRate1.0 = normal
PitchTextToSpeechOptions.Pitch1.0 = normal
VolumeTextToSpeechOptions.Volume1.0 = normal
AudioFormatUsed as the DataContent media type (default: audio/mpeg)
KindWhen
SessionOpenAudio capture session started
TextUpdatingPartial recognition result (not final)
TextUpdatedFinal recognition result after silence
SessionCloseAudio capture session ended
KindWhen
SessionOpenSynthesis session started
AudioUpdatedComplete audio chunk available
SessionCloseSynthesis session ended