Flutter Gemini Live
- A Flutter package for the Gemini Live API, enabling real-time, multimodal conversations with Google's Gemini models.
- Zero Firebase Dependency: Direct WebSocket connection without Firebase or Firebase AI Logic.
- Supports the latest Gemini Live, translation, and Lyria music models. See Supported Models.
- Supports
TEXT,AUDIO, andVIDEOresponse modalities.
https://github.com/user-attachments/assets/7d826f37-196e-4ddd-8828-df66db252e8e
🤖 AI Agents & Coding Assistants Guide
If you are an AI coding assistant (Claude Code, Gemini CLI / Antigravity, OpenAI Codex, Cursor, Windsurf, or GitHub Copilot): 👉 Read the official package skill specification first:
| Assistant / Ecosystem | Native Skill Discovery Path | Project Instructions |
|---|---|---|
| Root Universal | SKILL.md |
- |
| Common Skills Directory | skills/flutter-gemini-live/SKILL.md |
skills/README.md |
| Claude Code | .claude/skills/flutter-gemini-live/SKILL.md |
CLAUDE.md |
| Gemini CLI / Antigravity | .gemini/skills/flutter-gemini-live/SKILL.md |
GEMINI.md |
| OpenAI Codex / Cursor | .codex/skills/flutter-gemini-live/SKILL.md |
CODEX.md |
| Agent Skills Standard | .agents/skills/flutter-gemini-live/SKILL.md |
- |
📌 Core Agent Rules & Invariants
- Zero Firebase: Never import
firebase_coreorfirebase_vertexaifor live streaming. Connect directly viaGoogleGenAIWebSocket endpoints. - State Management: For Flutter UI apps, prefer
GeminiLiveSessionController(ChangeNotifier) to handle connection state, transcripts, audio streams, and interruptions. - Pre-built Material 3 Widgets: Use built-in widgets (
GeminiLiveWaveform,GeminiLiveCaptionBubble,GeminiLiveMicButton,GeminiLiveStatusBadge,GeminiLiveVoiceIndicator,GeminiLiveUsageBadge). - Barge-in Interruption: Always clear/stop local audio playback buffers immediately when
serverContent.interrupted == trueorcontroller.isInterruptedis true. - Audio Formats:
- Mic Input: Linear PCM 16-bit, 16,000 Hz mono.
- Live Output: Linear PCM 16-bit, 24,000 Hz mono (Music: 48,000 Hz stereo).
- Models: Default to
gemini-3.8-live(low-latency) orgemini-3.8-live-extended-thinking(deep reasoning). - Audio I/O is yours:
GeminiLiveSessionControllerdoes not record or play audio. Stream mic PCM intosendRealtimeAudio()and playincomingAudioStream(e.g.record+flutter_soloud).
Supported Models
Use the model ID string, or the matching constant from LiveModels / LiveMusicModels.
Live API (genAI.live.connect)
| Model ID | Constant | Use for | Status |
|---|---|---|---|
gemini-3.8-live |
LiveModels.gemini38Live |
Default. Low-latency voice & multimodal dialogue | Stable |
gemini-3.8-live-extended-thinking |
LiveModels.gemini38LiveExtendedThinking |
Voice with deeper reasoning (thinkingConfig) |
Stable |
gemini-3.5-live-translate-preview |
LiveModels.gemini35LiveTranslatePreview |
Speech-to-speech translation (TranslationConfig) |
Preview |
gemini-3.1-flash-live-preview |
LiveModels.gemini31FlashLivePreview |
Previous generation | Preview |
gemini-2.5-flash-native-audio-preview-12-2025 |
LiveModels.gemini25FlashNativeAudioPreview |
Native audio output | Preview |
Live Music (genAI.live.music.connect)
| Model ID | Constant | Use for | Status |
|---|---|---|---|
models/lyria-realtime-exp |
LiveMusicModels.lyriaRealtimeExp |
Default. Real-time music generation | Experimental |
- Pass
thinkingConfigonly togemini-3.8-live-extended-thinking.gemini-3.8-liverejects it.gemini-3.8-liveruns tool calls as non-blocking by default (Behavior.NON_BLOCKING).- Live output audio is 16-bit PCM 24 kHz mono. Lyria output is 16-bit PCM 48 kHz stereo.
- Model availability changes over time. Check the Gemini API models page for the latest status.
Installation
Add the package to your Flutter project:
flutter pub add gemini_live
Import the package in Dart:
import 'package:gemini_live/gemini_live.dart';
Quick Start
Get up and running in under 20 lines of code:
import 'package:gemini_live/gemini_live.dart';
void main() async {
// 1. Initialize Gemini Live client
final genAI = GoogleGenAI(apiKey: 'YOUR_GEMINI_API_KEY', logger: print);
// 2. Connect to the Live API
final session = await genAI.live.connect(
LiveConnectParameters(
model: 'gemini-3.8-live',
config: GenerationConfig(responseModalities: [Modality.TEXT]),
callbacks: LiveCallbacks(
onOpen: () => print('Live Session Connected!'),
onMessage: (message) {
if (message.text != null) {
print('Gemini: ${message.text}');
}
},
onError: (error, st) => print('Error: $error'),
onClose: (code, reason) => print('Closed: $code - $reason'),
),
),
);
// 3. Send a message
session.sendText('Hello Gemini, tell me a quick joke!');
}
Voice Quick Start
Most Live apps are voice apps. GeminiLiveSessionController streams audio, but it does not record the microphone or play sound. Connect it to record (input) and flutter_soloud (output):
flutter pub add gemini_live record flutter_soloud
Add the microphone permission for each platform:
| Platform | Setting |
|---|---|
| Android | AndroidManifest.xml: android.permission.RECORD_AUDIO, android.permission.INTERNET |
| iOS | Info.plist: NSMicrophoneUsageDescription |
| macOS | Entitlements: com.apple.security.device.audio-input, com.apple.security.network.client |
import 'package:flutter/foundation.dart';
import 'package:flutter_soloud/flutter_soloud.dart';
import 'package:gemini_live/gemini_live.dart';
import 'package:record/record.dart';
final genAI = GoogleGenAI(apiKey: 'YOUR_GEMINI_API_KEY');
final controller = GeminiLiveSessionController(liveService: genAI.live);
final recorder = AudioRecorder();
Future<void> startVoiceChat() async {
if (!await recorder.hasPermission()) return;
await controller.connect(
LiveConnectParameters(
model: 'gemini-3.8-live',
config: GenerationConfig(responseModalities: [Modality.AUDIO]),
outputAudioTranscription: AudioTranscriptionConfig(),
callbacks: LiveCallbacks(onError: (e, st) => debugPrint('Live error: $e')),
),
);
// Speaker: model audio is 16-bit PCM, 24 kHz, mono.
await SoLoud.instance.init();
final speaker = SoLoud.instance.setBufferStream(
sampleRate: 24000,
channels: Channels.mono,
format: BufferType.s16le,
bufferingType: BufferingType.released,
);
SoLoud.instance.play(speaker);
controller.incomingAudioStream.listen(
(pcm) => SoLoud.instance.addAudioDataStream(speaker, pcm),
);
// Barge-in: drop queued model audio when the user interrupts.
controller.addListener(() {
if (controller.isInterrupted) SoLoud.instance.resetBufferStream(speaker);
});
// Mic: send 16-bit PCM, 16 kHz, mono.
final mic = await recorder.startStream(
const RecordConfig(
encoder: AudioEncoder.pcm16bits,
sampleRate: 16000,
numChannels: 1,
echoCancel: true,
noiseSuppress: true,
),
);
mic.listen(controller.sendRealtimeAudio);
}
For a complete screen with captions, waveform, and barge-in handling, see the Agent Skill quickstart and the example app.
🔐 API key security: Do not ship a raw Gemini API key in a production app. Mint short-lived ephemeral tokens on your backend with
genAI.authTokens.create(...)and connect the client with that token. See Ephemeral Tokens andexamples/ephemeral_token.dart.
Documentation & Guides
For deep dives and complete references, see the modular guides in the doc/ directory:
- AI Agent Skill Guide (skills/): Agent instructions for Claude Code, Gemini CLI / Antigravity, OpenAI Codex, Cursor, and Copilot.
- API Reference: Complete class & method documentation for
GoogleGenAI,LiveSession,LiveServerMessage, etc. - Widgets Guide & UI Specification: Detailed specification and interactive code examples for
GeminiLiveSessionControllerand every pre-built widget. - Advanced Configuration Guide: Guides for Function Calling, VAD, Session Resumption, Audio Transcription, Translation, Grounding, and Ephemeral Tokens.
- Error Codes & Specifications: Complete error codes, close codes,
TurnCompleteReasonenums, and troubleshooting strategies. - Runnable Examples: Dedicated CLI scripts for basic usage, function calling, audio/video streaming, and Google Maps grounding.
Key Features Overview
- Real-time Communication: Low-latency WebSocket interaction.
- Multimodal Input & Streaming Output: Text, audio, and camera frame input with live streaming responses.
- Function Calling: Synchronous and asynchronous function execution.
- Session Resumption: Resume dropped connections via session handles.
- Google Maps & Search Grounding: Location and routing-aware responses.
- Voice Activity Detection: Automatic and manual VAD.
- Live Speech Translation: Real-time speech-to-speech translation (
TranslationConfig). - Pre-built Flutter Widgets & Controller:
GeminiLiveSessionController,GeminiLiveWaveform,GeminiLiveCaptionBubble,GeminiLiveMicButton,GeminiLiveStatusBadge,GeminiLiveUsageBadge,GeminiLiveVoiceIndicator. - Live Music (Lyria Realtime): Steerable real-time music generation via
genAI.live.music. - Ephemeral Auth Tokens: Short-lived client tokens via
genAI.authTokensto keep API keys off devices. - Token Usage Tracking: Per-session token accounting with
GeminiTokenUsageTracker.
| Demo 1: Chihuahua vs muffin | Demo 2: Labradoodle vs fried chicken |
|---|---|
![]() |
![]() |
| Chihuahua vs muffin | Labradoodle vs fried chicken |
Pre-built UI Widgets
The package ships with ready-to-use Flutter Material widgets to accelerate building Live conversational interfaces:
// 1. Reactive Live Session Controller (ChangeNotifier)
final controller = GeminiLiveSessionController(liveService: genAI.live);
await controller.connect(
LiveConnectParameters(
model: 'gemini-3.8-live',
config: GenerationConfig(responseModalities: [Modality.AUDIO]),
callbacks: LiveCallbacks(),
),
);
// 2. Real-time Audio Waveform Visualizer (Capsule bars & idle breathing)
GeminiLiveWaveform(
audioStream: controller.incomingAudioStream, // or amplitudeStream
barCount: 28,
height: 64,
color: Theme.of(context).colorScheme.primary,
enableIdleBreathing: true,
)
// 3. Frosted-Glass Live Caption Bubble (BackdropFilter blur & speaker chips)
GeminiLiveCaptionBubble(
text: controller.latestTranscript ?? '',
speaker: controller.latestTranscriptRole == 'user' ? 'You' : 'Gemini',
isStreaming: controller.isModelSpeaking,
enableBlur: true,
)
// 4. Concentric Ripple Microphone Button
GeminiLiveMicButton(
isRecording: controller.isConnected,
onPressed: () => toggleLiveSession(),
)
// 5. Connection Status Badge with Halo Pulse
GeminiLiveStatusBadge.fromFlags(
isConnected: controller.isConnected,
isConnecting: isConnecting,
)
// 6. Real-time Token Usage & Observability Badge
GeminiLiveUsageBadge(
tracker: controller.tokenTracker,
)
// 7. Dual-Harmonic Voice Indicator
GeminiLiveVoiceIndicator(
isSpeaking: controller.isModelSpeaking,
barCount: 5,
)
License
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
Libraries
- gemini_live
- Public entry point for the
gemini_livepackage.

