πŸ‡ͺπŸ‡¬  Proudly Made in Egypt

Talk It

Simple native speech-to-text for Flutter. Talk, get text.

pub.dev Platform License: MIT

Platform Speech
Android βœ…
iOS βœ…

Uses platform-native recognizers only β€” no cloud APIs, no third-party STT SDKs.

  • Android: SpeechRecognizer + RecognizerIntent (Google app preferred)
  • iOS: Speech framework (SFSpeechRecognizer, AVAudioEngine)

Features

  • πŸŽ™οΈ Native on-device recognition β€” no internet required
  • πŸ‡ͺπŸ‡¬ Battle-tested Arabic (ar-EG) support
  • πŸ” Two listening modes: auto-stop on silence or push-to-talk
  • πŸͺΆ Minimal dependencies β€” Flutter only
  • πŸ”Œ Simple, familiar API

Install

dependencies:
  talk_it: ^0.1.0

Permissions

The plugin does not request permissions automatically. Add them in your app.

Android β€” android/app/src/main/AndroidManifest.xml

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

<queries>
  <intent>
    <action android:name="android.speech.RecognitionService"/>
  </intent>
</queries>

πŸ’‘ Install the Google app on the device for best results, especially for Arabic.

iOS β€” ios/Runner/Info.plist

<key>NSMicrophoneUsageDescription</key>
<string>We need the microphone for voice input.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>We need speech recognition to transcribe your voice.</string>

Request permissions at runtime (e.g. with permission_handler):

import 'dart:io';
import 'package:permission_handler/permission_handler.dart';

Future<bool> ensureMic() async {
  if (!await Permission.microphone.request().isGranted) return false;
  if (Platform.isIOS && !await Permission.speech.request().isGranted) return false;
  return true;
}

Quick Start

import 'package:talk_it/talk_it.dart';

final talk = TalkIt();

Future<void> start() async {
  final ok = await talk.initialize();
  if (!ok) return;

  await ensureMic();

  await talk.listen(onResult: (result) {
    print(result.recognizedWords); // live + final text
    if (result.isFinal) {
      // done β€” send to your API, update UI, etc.
    }
  });
}

// later…
await talk.stop();   // manual stop (push-to-talk mode)
await talk.cancel(); // discard session

Complete Flutter Example

import 'package:flutter/material.dart';
import 'package:talk_it/talk_it.dart';

class VoicePage extends StatefulWidget {
  const VoicePage({super.key});
  @override
  State<VoicePage> createState() => _VoicePageState();
}

class _VoicePageState extends State<VoicePage> {
  final TalkIt _talk = TalkIt();
  bool _enabled = false;
  String _words = '';

  @override
  void initState() {
    super.initState();
    _init();
  }

  Future<void> _init() async {
    _enabled = await _talk.initialize(
      localeId: 'ar-EG',
      onStatus: (s) => debugPrint(s),
      onError: (e) => debugPrint(e),
    );
    setState(() {});
  }

  Future<void> _start() async {
    await _talk.listen(
      onResult: (r) => setState(() => _words = r.recognizedWords),
    );
    setState(() {});
  }

  Future<void> _stop() async {
    await _talk.stop();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Talk It')),
      body: Center(
        child: Text(
          _talk.isListening
              ? _words
              : (_enabled ? 'Tap mic…' : 'Not available'),
          textDirection: TextDirection.rtl,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _talk.isNotListening ? _start : _stop,
        child: Icon(_talk.isNotListening ? Icons.mic : Icons.stop),
      ),
    );
  }
}

Listening Modes

Auto-stop on silence (default)

Stops automatically after a brief pause β€” great for single commands or short phrases.

await talk.listen(
  onResult: (r) => print(r.recognizedWords),
  listenOptions: const TalkItListenOptions(
    mode: TalkItMode.untilSilence,
  ),
);

Push-to-talk

Keeps listening through pauses until you explicitly call stop(). Ideal for longer dictation or noisy environments.

await talk.listen(
  onResult: (r) => print(r.recognizedWords),
  listenOptions: const TalkItListenOptions(
    mode: TalkItMode.untilStopped,
  ),
);

// User speaks with long pauses…
await talk.stop(); // final result delivered via onResult with isFinal: true

Arabic Support

talk_it was built with Arabic-first reliability in mind.

final talk = TalkIt();
await talk.initialize(localeId: 'ar-EG');

await talk.listen(
  localeId: 'ar-EG',
  onResult: (r) {
    if (r.isFinal) sendToLlm(r.recognizedWords);
  },
);

API Reference

Methods

Method Description
initialize() Call once per app session. Returns true if STT is available.
listen(onResult:) Start listening. onResult fires for both partial and final results.
stop() End the session and receive the final result.
cancel() Abort the session without a final result.

Properties

Property Type Description
isListening bool true while a session is active.
isNotListening bool Inverse of isListening.
isAvailable bool true after a successful initialize().
lastWords String Last recognized text from any session.

TalkItResult

Field Type Description
recognizedWords String Current transcript (partial or final).
isFinal bool true when the recognition session has ended.

Audio & Sounds

The plugin does not play sounds. Use your own audio player before or after listen() / stop().

  • Android: System beeps are muted during sessions.
  • iOS: Uses mixWithOthers so existing app audio continues uninterrupted.

Running the Example App

cd example
flutter run

Publishing

flutter pub publish --dry-run

License

MIT Mohab Gamal all rights reserved Β© Made with ❀️ in Egypt πŸ‡ͺπŸ‡¬

Libraries

talk_it