azure_speech_services 1.0.1 copy "azure_speech_services: ^1.0.1" to clipboard
azure_speech_services: ^1.0.1 copied to clipboard

A Flutter package for real-time Speech-to-Text, Text-To-Speech transcription, and Translation using Microsoft Azure Cognitive Services. Supports Mobile, Desktop, and Web platforms

Azure Speech Services #

A Flutter package for real-time Speech-to-Text (STT), Text-to-Speech (TTS), Realtime-Translation using Microsoft Azure Cognitive Services. No Azure SDK binary dependency: it communicates directly with the Azure WebSocket/REST APIs.

  • STT: Stream-based real-time transcription with intermediate (hypothesis) and finalized results, multi-language identification (LID), and auto-silence timeout.
  • TTS: Synthesize text to audio bytes using any Azure Neural voice, with configurable output format. *. Translation: Stream-based real-time translation in many different languages
  • Cross-platform: Mobile (iOS, Android), Desktop (macOS, Windows, Linux), and Web.

Example app #


Getting Started #

Installation #

import 'package:azure_speech_services/azure_speech_services.dart';

Authentication #

Both STT and TTS use the same AzureSpeechConfig. You must provide exactly one credential:

// Option A: Subscription Key
final config = AzureSpeechConfig.subscriptionKey(
  region: 'westeurope', // or other supported region
  key: 'YOUR_AZURE_KEY',
);

// Option B: Short-lived Authorization Token (recommended for Web)
final config = AzureSpeechConfig.authorizationToken(
  region: 'westeurope', // or other supported region
  token: 'YOUR_BACKEND_GENERATED_TOKEN',
);

Web security note: Browser WebSocket APIs cannot set custom HTTP headers. On Web, auth is passed as a URL query parameter. Always use authorizationToken (generated server-side) on Web: never expose subscriptionKey in the browser URL.

To generate a short-lived token:

curl -X POST \
  "https://westeurope.api.cognitive.microsoft.com/sts/v1.0/issueToken" \
  -H "Content-Length: 0" \
  -H "Ocp-Apim-Subscription-Key: YOUR_KEY"

Speech-to-Text (STT) #

Permissions #

STT requires microphone access. TTS does not.

Androidandroid/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

iOSios/Runner/Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access for speech recognition.</string>

macOSmacos/Runner/DebugProfile.entitlements and Release.entitlements:

<key>com.apple.security.device.audio-input</key>
<true/>

Basic usage #

final azureStt = AzureSpeechToText(
  config: AzureSpeechConfig.subscriptionKey(
    region: 'westeurope', // or other supported region
    key: 'YOUR_AZURE_KEY',
  ),
  sttConfig: SpeechToTextConfig(
    languages: ['en-US'],
    textClearTimeout: const Duration(seconds: 2),
  ),
);

// Start / stop
await azureStt.start();
await azureStt.stop();

// Check state
azureStt.isListening;

// Dispose when done
await azureStt.dispose();

Listening to transcription updates #

azureStt.stream emits TranscriptionState on every change:

StreamBuilder<TranscriptionState>(
  stream: azureStt.stream,
  builder: (context, snapshot) {
    final state = snapshot.data ?? const TranscriptionState();

    if (state.error != null) return Text('Error: ${state.error}');

    return Column(
      children: [
        if (state.detectedLanguage != null)
          Text('Detected: ${state.detectedLanguage}'),
        // Combined text (finalized + intermediate)
        Text(state.text),
        // state.intermediateText // live hypothesis (no punctuation)
        // state.finalizedText   // list of confirmed sentences
        // state.isListening     // mic active
      ],
    );
  },
)

Using the BLoC cubit #

AzureSpeechToText owns a TranscriptionCubit. Provide it higher in the widget tree to avoid rebuilding the whole subtree:

BlocProvider.value(
  value: azureStt.cubit,
  child: MyWidget(),
)

// Then in a descendant:
BlocBuilder<TranscriptionCubit, TranscriptionState>(
  builder: (context, state) => Text(state.text),
)

Language Identification (LID) #

The number of languages you provide determines the mode automatically:

Mode Languages count
Single language (fastest) 1
At-Start LID 1 - 4
Continuous LID 1 - 10

Bare language codes are expanded automatically ("it""it-IT").

// Single language: fastest, no identification overhead
SpeechToTextConfig(languages: ['en-US'])

// At-Start: identifies once at the beginning of the session
SpeechToTextConfig(
  languages: ['en-US', 'it', 'es-ES', 'fr-FR'],
  languageIdMode: .atStart, // default
)

// Continuous: re-identifies throughout the session, up to 10 languages
SpeechToTextConfig(
  languages: ['en-US', 'it-IT', 'es-ES', 'de-DE', 'pt-PT', 'nb-NO', 'sv-SE', 'uk-UA'],
  languageIdMode: .continuous,
)

External audio stream #

To bypass the microphone (e.g. VoIP or file audio), pass your own Stream<Uint8List> to start(). It must emit raw PCM: 16 kHz, mono, 16-bit little-endian — the same format the microphone produces.

await azureStt.start(); // uses mic by default

// or supply your own audio source instead
await azureStt.start(externalAudioStream: myPcmStream);

Text-to-Speech (TTS) #

No microphone permissions required.

Basic usage #

final azureTts = AzureTextToSpeech(
  config: AzureSpeechConfig.subscriptionKey(
    region: 'westeurope', // or other supported region
    key: 'YOUR_AZURE_KEY',
  ),
);

// 1. Fetch available voices
final voices = await azureTts.listVoices();

// 2. Pick a voice
final voice = voices.firstWhere(
  (v) => v.locale == 'en-US' && v.gender == 'Female',
  orElse: () => voices.first,
);

// 3. Synthesize: returns raw audio bytes
final audioBytes = await azureTts.synthesize(
  TtsRequest(
    text: 'Hello from Azure Speech Flutter!',
    voice: voice,
    outputFormat: .audio16khz128kbitrateMonoMp3, // default
  ),
);

Output formats #

AudioOutputFormat covers MP3, PCM, mulaw, Opus, and WebM at various sample rates and bitrates. The default is audio16khz128kbitrateMonoMp3.

Playing the audio #

The package returns raw bytes. Plug them into any audio player. Example with just_audio:

class _BytesAudioSource extends StreamAudioSource {
  final List<int> bytes;
  _BytesAudioSource(this.bytes) : super(tag: 'tts');

  @override
  Future<StreamAudioResponse> request([int? start, int? end]) async {
    start ??= 0;
    end ??= bytes.length;
    return StreamAudioResponse(
      sourceLength: bytes.length,
      contentLength: end - start,
      offset: start,
      contentType: 'audio/mpeg',
      stream: Stream.value(Uint8List.fromList(bytes.sublist(start, end))),
    );
  }
}

final player = AudioPlayer();
await player.setAudioSource(_BytesAudioSource(audioBytes));
await player.play();

Voice metadata #

Each TtsVoice exposes:

Field Description
name Azure short name (e.g. en-US-JennyNeural)
locale BCP-47 locale (e.g. en-US)
localeName Locale display name (e.g. English (United States))
localName Voice display name in its own language
gender "Male" or "Female"

License #

MIT. See LICENSE.

0
likes
150
points
36
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package for real-time Speech-to-Text, Text-To-Speech transcription, and Translation using Microsoft Azure Cognitive Services. Supports Mobile, Desktop, and Web platforms

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

equatable, flutter, flutter_bloc, http, record, uuid, web_socket_channel

More

Packages that depend on azure_speech_services