VOIP Flutter Application
September 30, 2025 Β· View on GitHub
MediaSFU reference client for Flutter showcasing a configurable dialer, MediaSFU room monitoring, and SIP provisioning on iOS, Android, and desktop targets.
Agent orchestration superpowers
- Agent-only concierge flows leverage MediaSFU Agents for zero-touch onboarding before humans step in.
- One-tap human takeover mirrors the React Native and web experience via the shared
MediasfuRoomDisplaywidget.- Blended agent + human routing swaps sources without audio drops, including hold/resume and bot coaching.
- Smart audio broadcast controls let you flip between caller-only prompts and play-to-all announcements mid-call.
Prebuilt downloads
Start testing instantly with the latest signed artifacts built from this project:
- πͺ Windows desktop installer: MediaSFU-Setup.exe
- π€ Android APK (Flutter): mediasfu-voip-flutter.apk
βΉοΈ macOS
.appbundles and iOS TestFlight links are plannedβwatch this space as the desktop and iOS release tracks open up.
Table of contents
- Overview
- Key features
- Project structure
- Getting started
- Configuration
- MediaSFU flows
- Permissions
- Build targets
- Troubleshooting
- Contributing
Overview
CallsPage is the primary entry point. It mirrors the React client by:
- Managing MediaSFU API credentials through
VoipConfigProvider(stored withSharedPreferences). - Polling MediaSFU call endpoints via
CallServicewith back-off and caching. - Rendering active calls, room details, and history with timers for live durations.
- Providing dialpad and SIP configuration loading in one screen.
State is coordinated through Provider (VoipConfigProvider, CallManagerProvider) and room rendering uses MediasfuRoomDisplay.
Key features
- Dialer β Pre-populated β+β prefix and ergonomic input with duration presets.
- MediaSFU room monitor β Displays the connected room, participant name, and microphone toggle state.
- Active call polling β Polls active calls every few seconds, with configurable back-off when rate limited.
- Call history snapshots β Maintains a limited list of past calls with status, timestamps, and duration fallback logic.
- SIP configuration fetch β Retrieves SIP credentials once API keys are supplied and surfaces error details.
- Theme toggle β Users can switch between light and dark themes at runtime with persistence.
- Desktop-ready layout β Resize-aware panels suitable for macOS/Windows builds.
The sample currently focuses on audio call orchestration. Video calls, push notifications, and background calling are not implemented.
Project structure
voip_flutter/
βββ lib/
β βββ pages/
β β βββ calls_page.dart
β βββ providers/
β β βββ voip_config_provider.dart
β β βββ call_manager_provider.dart
β βββ services/
β β βββ call_service.dart
β β βββ config_service.dart
β βββ types/
β β βββ call_types.dart
β β βββ api_types.dart
β β βββ sip_config_types.dart
β βββ utils/
β β βββ logger.dart
β βββ widgets/
β βββ mediasfu_room_display.dart
βββ assets/
βββ android/ | ios/ | windows/ (platform folders)
βββ pubspec.yaml
Getting started
Prerequisites
- Flutter SDK 3.35.4 (or later patch in the 3.35 line)
- Dart 3.4.3+
- Xcode 15+ for iOS builds (macOS)
- Android Studio with SDK 24+ for Android
Install and run
flutter --version
flutter pub get
flutter run
Use flutter devices to select a specific simulator or physical device.
Configuration
Configuration lives under Settings β API Configuration inside the app. Behind the scenes VoipConfigProvider persists values via SharedPreferences.
| Setting | Purpose | Notes |
|---|---|---|
| API username | MediaSFU account username | Required for call placement |
| API key | MediaSFU API key | Stored locally; clear via βResetβ |
| Base URL | MediaSFU REST endpoint | Defaults to https://mediasfu.com |
| Theme | Light or dark | Toggle in Settings or AppBar |
The first successful credential save triggers loadSipConfig, which requests SIP configs from MediaSFU (/v1/sipconfigs/). Errors (401/403/etc.) are surfaced in the UI.
MediaSFU flows
CallService.makeCallposts to the MediaSFU call endpoint using stored credentials.- Active calls are cached briefly (
_apiCallCacheTimeout) to avoid rate limits. CallManagerProviderrefreshes state on timers and processes room switch events.MediasfuRoomDisplayrenders current room metadata and microphone state.- History is capped through
CallManagerProvider.MAX_HISTORY_RECORDSto reduce memory usage.
Logging utilities (Logger.info/error) mirror the React client to keep diagnostics consistent across platforms.
Permissions
Android
Declared in android/app/src/main/AndroidManifest.xml:
| Permission | Purpose |
|---|---|
INTERNET | MediaSFU API + signaling |
CAMERA | Reserved for future video support (currently unused) |
RECORD_AUDIO | Capture microphone for VOIP calls |
ACCESS_NETWORK_STATE | Detect connectivity changes for polling back-off |
CHANGE_NETWORK_STATE | Allow network adjustments if needed by plugins |
MODIFY_AUDIO_SETTINGS | Control audio routing and gain for call quality |
BLUETOOTH / BLUETOOTH_ADMIN (<= API 30) | Legacy classic Bluetooth audio routing |
BLUETOOTH_CONNECT | Required for managing Bluetooth headsets (API 31+) |
Optional you may add later depending on features:
| Potential Permission | When Needed |
|---|---|
POST_NOTIFICATIONS | In-app/push call alerts (Android 13+) |
FOREGROUND_SERVICE (+ media type) | Background ongoing call service |
WAKE_LOCK | Prevent device sleep during active call |
iOS
Added to ios/Runner/Info.plist:
| Key | Purpose |
|---|---|
NSMicrophoneUsageDescription | Microphone access for VOIP calling |
NSCameraUsageDescription | Placeholder for future video/media features |
(If adding CallKit or push notifications later include NSBluetoothAlwaysUsageDescription, NSUserNotificationUsageDescription, and configure VoIP push entitlements.)
Build targets
| Target | Command | Output |
|---|---|---|
| Android APK | flutter build apk --release | build/app/outputs/flutter-apk/app-release.apk |
| Android App Bundle | flutter build appbundle --release | build/app/outputs/bundle/release/app-release.aab |
| iOS | flutter build ios --release (then archive in Xcode) | Runner archive |
| Windows | flutter build windows --release | build/windows/runner/Release |
| macOS | flutter build macos --release | build/macos/Build/Products/Release |
Before releasing, update icons via flutter pub run flutter_launcher_icons:main if brand assets change.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| βAuthentication failedβ toast | Invalid username or API key | Re-enter credentials, verify on https://mediasfu.com/telephony |
| SIP configs never load | Permissions missing on MediaSFU tenant | Confirm account has SIP provisioning rights |
| Calls remain in dialing | MediaSFU tenant not enabled for outbound | Contact MediaSFU support |
| Frequent polling errors | Network instability or rate limit | Allow the built-in back-off to reset, or increase interval |
Run flutter doctor to ensure your environment is correctly configured.
Contributing
- Clone the mono-repo and install dependencies:
flutter pub get. - Create a feature branch from
main. - Follow Dart style (
flutter format,flutter analyze). - Add or update tests in
test/where feasible. - Submit a pull request summarizing the change and impacted MediaSFU APIs.
Maintained by MediaSFU Engineering. Last updated September 25, 2025.