voip_audio_route_manager 1.1.3 copy "voip_audio_route_manager: ^1.1.3" to clipboard
voip_audio_route_manager: ^1.1.3 copied to clipboard

Flutter package for VoIP audio routing and management. Switch output between speakerphone, earpiece, wired headsets, and Bluetooth devices for WebRTC, SIP, and calling apps.

VoIP Audio Route Manager

pub package pub points Platform License: MIT Build Status GitHub Stars

A production-ready Flutter package for VoIP audio route switching, call audio routing, and Bluetooth audio output device management.

InstallationQuick StartFeaturesIntegrationsAPIFAQ


What is VoIP Audio Route Manager? #

VoIP Audio Route Manager is a complete Flutter audio manager and audio output device router for real-time device selection. It enables your Flutter app to easily detect, list, and switch audio output devices — including speakerphone, earpiece/receiver, wired headsets, and Bluetooth devices — across Android, iOS, macOS, and Web.

Built specifically for VoIP communication apps using WebRTC, SIP/VoIP, custom calling engines, and CallKit integrations, this package solves the common problem of unreliable audio routing in real-time communication apps.

Why Use This Package? #

If you are building a Flutter VoIP calling app, SIP client, WebRTC video/voice app, or any Flutter application that needs a reliable call audio route or VoIP audio route switch, this package gives you a single, consistent API across all platforms — eliminating the need to write complex native platform channels yourself.

💡 Problem it solves: Native audio routing APIs differ significantly across Android (AudioManager), iOS (AVAudioSession), macOS (CoreAudio), and Web (MediaDevices). This package unifies them into one clean Dart interface.


Table of Contents #


Features #

Feature Description
🔊 Real-Time Detection Automatically monitor audio output device additions, removals, and route switches in real time.
🔁 Unified Dart Streams Access route updates, device list changes, and audio focus events via simple, reactive Dart Streams.
🎯 Intelligent Switching Change the audio output route by device ID, device type, or device name with a single method call.
🎧 Bluetooth Route Switch Detect and switch to/from Bluetooth headsets, earbuds, and car audio seamlessly.
🔈 Speaker / Earpiece Toggle One-line calls to flip between speakerphone and receiver during active calls.
🎚️ Audio Focus & Detection React to native audio focus state changes (gained/lost), Bluetooth connection states, and headphone plug/unplug events.
📞 Platform-Specific APIs Uses Android's modern setCommunicationDevice API (Android 12+) with legacy SCO fallback, iOS AVAudioSession output overrides, macOS CoreAudio, and the Web MediaDevices API.
🤝 Clean Coexistence Designed to run alongside audio_session, flutter_webrtc, sip_ua, and custom calling engines without conflict.

Supported Platforms #

Platform Support Minimum Version Notes
Android ✅ Full API 21+ (Android 5.0) Uses setCommunicationDevice on Android 12+, SCO fallback on older versions.
iOS ✅ Full iOS 11.0+ Uses AVAudioSession category and mode overrides.
macOS ✅ Full macOS 10.14+ Uses CoreAudio device enumeration and selection.
Web ✅ Full Modern browsers Uses MediaDevices.enumerateDevices() and HTMLMediaElement.setSinkId().

⚠️ Windows and Linux are not yet supported. See Issue #42 for progress.


Installation #

Add this dependency to your pubspec.yaml:

dependencies:
  voip_audio_route_manager: ^1.1.0

Then run:

flutter pub get

Quick Start #

Get up and running in under 30 seconds:

import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

void main() async {
  final manager = VoipAudioRouteManager.instance;

  // 1. Initialize
  await manager.initialize(enableLogs: true);

  // 2. Start a call session
  await manager.startCallSession();

  // 3. List available devices
  final devices = await manager.availableDevices();
  print(devices);

  // 4. Switch to speakerphone
  await manager.setAudioRouteType(AudioOutputType.speaker);

  // 5. End the call session
  await manager.endCallSession();
}

Basic Usage #

Initialization #

import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

final manager = VoipAudioRouteManager.instance;

// Optional: Enable debug logs
await manager.initialize(enableLogs: true);

// Activate native VoIP audio mode/focus when a call starts
await manager.startCallSession();

// Release route/focus requests when the call ends
await manager.endCallSession();

Fetch Devices & Current Route #

// Get all available output devices
final List<AudioOutputDevice> devices = await manager.availableDevices();

// Get the currently active output route
final AudioOutputDevice? currentRoute = await manager.currentAudioRoute();

Listening to Streams #

// Listen to all available devices list updates
manager.audioDevicesStream.listen((devices) {
  print("Available devices: $devices");
});

// Listen to active route changes
manager.onRouteChanged.listen((device) {
  print("Now playing on: ${device.name}");
});

// Listen to audio focus status (e.g., paused due to phone calls)
manager.onAudioFocusChanged.listen((focused) {
  print("Audio focus active: $focused");
});

Switching Routes #

// Switch by device object
await manager.setAudioRoute(device);

// Switch by ID
await manager.setAudioRouteById("device_id_here");

// Switch by device type
await manager.setAudioRouteType(AudioOutputType.speaker);

// Switch by name (matches substring case-insensitively) — great for Bluetooth route switch
await manager.setAudioRouteByName("AirPods Pro");

Verified Route Switching #

// Returns requested route, actual route, status, and diagnostics.
final AudioRouteResult result =
    await manager.selectAudioRouteType(AudioOutputType.speaker);

if (!result.success) {
  print("Route failed: ${result.status} ${result.message}");
}

// Clear explicit routing and return to platform default behavior.
await manager.clearAudioRoute();

Integration Guides #

1. Integrating with flutter_webrtc #

WebRTC manages its own input/output track states. When using voip_audio_route_manager alongside flutter_webrtc:

import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

Future<void> switchToWebRTCDevice(AudioOutputDevice device) async {
  final manager = VoipAudioRouteManager.instance;

  if (Theme.of(context).platform == TargetPlatform.iOS ||
      Theme.of(context).platform == TargetPlatform.android) {
    // Mobile OS handles routing globally via AudioManager/AVAudioSession
    await manager.setAudioRoute(device);
  } else {
    // On Web/Desktop, apply the selected device ID to Helper/HTML video elements
    await Helper.selectAudioOutput(device.id);
  }
}

📘 See the flutter_webrtc documentation for more details.

2. Integrating with audio_session #

If your app uses audio_session, configure it first before calling voip_audio_route_manager:

import 'package:audio_session/audio_session.dart';
import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

Future<void> setupAudio() async {
  final session = await AudioSession.instance;
  await session.configure(const AudioSessionConfiguration(
    avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
    avAudioSessionMode: AVAudioSessionMode.voiceChat,
    avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth,
    androidAudioAttributes: AndroidAudioAttributes(
      contentType: AndroidAudioContentType.speech,
      usage: AndroidAudioUsage.voiceCommunication,
    ),
  ));

  await VoipAudioRouteManager.instance.initialize(enableLogs: true);
}

📘 Read the audio_session package guide for session configuration patterns.

3. Integrating with sip_ua #

To toggle speakerphone inside a SIP session:

import 'package:sip_ua/sip_ua.dart';
import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

class CallStateListener implements SipUaHelperListener {
  final _audioManager = VoipAudioRouteManager.instance;

  @override
  void callStateChanged(Call call, CallState state) {
    if (state.state == CallStateEnum.CONFIRMED) {
      _audioManager.setAudioRouteType(AudioOutputType.receiver);
    }
  }

  void toggleSpeaker(bool enabled) {
    _audioManager.setAudioRouteType(
      enabled ? AudioOutputType.speaker : AudioOutputType.receiver,
    );
  }
}

📘 Check the sip_ua package documentation for SIP session management.

4. Integrating with CallKit #

For iOS apps using CallKit, ensure your audio session is configured before reporting the call:

import 'package:call_kit/call_kit.dart';
import 'package:voip_audio_route_manager/voip_audio_route_manager.dart';

Future<void> reportIncomingCall(String uuid) async {
  await VoipAudioRouteManager.instance.startCallSession();
  // ... report call to CallKit
}

📘 Refer to Apple's CallKit documentation for full integration details.


API Reference #

Method / Stream Description
initialize({enableLogs}) Initializes the manager, optionally with debug logging.
startCallSession() Activates native VoIP audio mode/focus when a call starts.
endCallSession() Releases route/focus requests when the call ends.
availableDevices() Returns all currently available output devices.
currentAudioRoute() Returns the currently active output route.
setAudioRoute(device) Switches to a specific device object.
setAudioRouteById(id) Switches route by device ID.
setAudioRouteType(type) Switches route by AudioOutputType (speaker, receiver, bluetooth, etc.).
setAudioRouteByName(name) Switches route by matching device name (case-insensitive substring).
selectAudioRouteType(type) Switches route and returns a verified AudioRouteResult with diagnostics.
clearAudioRoute() Clears explicit routing, returning to platform default behavior.
audioDevicesStream Stream of available device list updates.
onRouteChanged Stream of active route changes.
onAudioFocusChanged Stream of audio focus gained/lost events.

AudioOutputDevice Model #

class AudioOutputDevice {
  final String id;           // Unique device identifier
  final String name;         // Human-readable device name
  final AudioOutputType type; // Device category
}

enum AudioOutputType {
  speaker,    // Built-in loudspeaker
  receiver,   // Earpiece / phone speaker
  wired,      // 3.5mm headset or USB-C headphones
  bluetooth,  // Bluetooth headset, earbuds, or car audio
  unknown,    // Unrecognized device type
}

Troubleshooting & FAQ #

Why is my Bluetooth device not showing up? #

Ensure Bluetooth permissions are granted on Android (BLUETOOTH_CONNECT for API 31+). On iOS, ensure your AVAudioSession category options include allowBluetooth. On Web, ensure the user has granted microphone permissions — browsers hide device labels until permission is granted.

Can I use this with flutter_sound or just_audio? #

Yes. This package is designed to coexist with other audio packages. It manages the audio output route (which speaker/headset the sound comes out of), while packages like flutter_sound or just_audio manage the audio content (what sound is played). Initialize voip_audio_route_manager after configuring your primary audio package.

Why does route switching fail on some Android devices? #

Some OEMs (Samsung, Xiaomi, Huawei) customize the Android AudioManager behavior. The package includes a fallback to SCO (Bluetooth headset) routing and logs detailed diagnostics when enableLogs: true is set. If you encounter issues, please open an issue with device model and Android version.

How do I handle audio focus during incoming phone calls? #

Listen to onAudioFocusChanged and pause/resume your call audio accordingly. On Android, this maps to AudioManager.AUDIOFOCUS_LOSS. On iOS, it maps to AVAudioSession.interruptionNotification.

Is this package suitable for music apps? #

While technically possible, this package is optimized for VoIP and real-time communication use cases. For music playback apps, consider using audio_session directly for more granular audio session control.

How does this compare to audio_session? #

Feature voip_audio_route_manager audio_session
Primary purpose Audio output device routing Audio session configuration
Bluetooth switching ✅ Native + seamless ⚠️ Requires manual setup
Platform abstraction ✅ Unified API ⚠️ Platform-specific config
WebRTC/SIP integration ✅ Built-in guides ❌ Not specific
Best for VoIP calling apps General audio apps

💡 Tip: Use audio_session for session configuration, then voip_audio_route_manager for device routing.

Does it support Windows or Linux? #

Not yet. Windows and Linux support is on the roadmap. For now, use conditional imports:

import 'package:voip_audio_route_manager/voip_audio_route_manager.dart'
    if (dart.library.html) 'package:voip_audio_route_manager/voip_audio_route_manager_web.dart';

How do I report a bug or request a feature? #

Please open an issue on GitHub. Include your Flutter version, platform, and a minimal reproducible example.


Comparison with Alternatives #

Package Platforms Bluetooth WebRTC Ready Maintenance
voip_audio_route_manager Android, iOS, macOS, Web ✅ Full ✅ Yes ✅ Active
audio_session All Flutter platforms ⚠️ Manual ⚠️ Partial ✅ Active
flutter_audio_manager Android, iOS ❌ No ❌ No ❌ Inactive
sound_mode Android only ❌ No ❌ No ❌ Inactive
volume_controller All ❌ No ❌ No ✅ Active

Demo #

See real-time audio route switching (speaker ↔ earpiece ↔ Bluetooth ↔ wired headset) in action:

Android #

Android VoIP audio route switching demo - transitions between speakerphone, earpiece, Bluetooth headset, and wired headphones in real time
Android: Real-time detection and switching across all connected audio output devices.

Web #

Web browser audio output device selection demo - listing and switching between speaker, Bluetooth, and headset via MediaDevices API
Web: Device labels populate after media permission grant; route changes reflect immediately.


Contributing & Local Development #

We welcome contributions! This project is structured as a Federated Flutter Plugin with separate packages for each platform.

Repository Structure #

voip_audio_route_manager/                    # Client app-facing package
├── voip_audio_route_manager_platform_interface/  # Contract definition
├── voip_audio_route_manager_android/        # Android implementation
├── voip_audio_route_manager_ios/            # iOS implementation
├── voip_audio_route_manager_macos/          # macOS implementation
└── voip_audio_route_manager_web/            # Web implementation

Getting Started #

  1. Fork the repository
  2. Install FVM and run fvm install
  3. Run melos bootstrap to link all packages
  4. Make your changes and add tests
  5. Ensure all CI checks pass: melos run analyze && melos run test
  6. Submit a Pull Request

📘 Read the full Contributing Guide for details.


Changelog #

See the CHANGELOG.md for a complete history of releases and breaking changes.

Recent Highlights #

  • v1.1.0 — Added macOS support, improved Bluetooth detection on Android 14+, Web MediaDevices fallback.
  • v1.0.0 — Stable release with Android, iOS, and Web support.
  • v0.9.0 — Beta release with federated plugin architecture.

License #

This project is licensed under the MIT License.

MIT License

Copyright (c) 2024 [Your Name or Organization]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Made with ❤️ for the Flutter community.
pub.devGitHubIssues

4
likes
160
points
339
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter package for VoIP audio routing and management. Switch output between speakerphone, earpiece, wired headsets, and Bluetooth devices for WebRTC, SIP, and calling apps.

Homepage
Repository (GitHub)
View/report issues

Topics

#voip #audio-routing #webrtc #bluetooth #speakerphone

License

MIT (license)

Dependencies

flutter, voip_audio_route_manager_android, voip_audio_route_manager_ios, voip_audio_route_manager_macos, voip_audio_route_manager_platform_interface, voip_audio_route_manager_web

More

Packages that depend on voip_audio_route_manager

Packages that implement voip_audio_route_manager