πͺπ¬ Proudly Made in Egypt
Talk It
Simple native speech-to-text for Flutter. Talk, get text.
| 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
mixWithOthersso 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 πͺπ¬