setSpeakerOutputPreferred method

Future<void> setSpeakerOutputPreferred(
  1. bool preferred, {
  2. bool force = false,
})

Prefers routing audio output to/from the speaker.

By default a connected wired/Bluetooth headset still takes priority even when preferred is true. Set force to force the speaker even when a headset is connected.

LiveKit owns this routing on both platforms (Android via its own audioswitch handler and iOS via its audio session), so it does not depend on flutter_webrtc.

Implementation

Future<void> setSpeakerOutputPreferred(bool preferred, {bool force = false}) async {
  if (!canSwitchSpeakerphone) {
    logger.warning('setSpeakerOutputPreferred is only supported on iOS/Android');
    return;
  }
  _preferSpeakerOutput = preferred;
  _forceSpeakerOutput = preferred && force;

  if (lkPlatformIs(PlatformType.iOS)) {
    if (_isAutomaticConfigurationEnabled) {
      final policy = _resolvedAudioSessionPolicy(_options);
      // Automatic mode: the native audio-engine delegate owns activation
      // timing, so this caches the policy and applies now only if the engine
      // is already running. Category is resolved natively from engine state.
      await Native.configureAudio(
        policy.appleConfiguration,
        automatic: true,
        selectCategoryByEngineState: true,
        forceSpeakerOutput: policy.forceSpeakerOutput,
      );
    } else {
      // Manual mode: re-apply the fixed Apple config. Non-forced receiver vs
      // speaker behavior comes from that config. Force is carried separately
      // to native for playAndRecord sessions.
      await _configureAppleAudioSession(_options);
    }
  } else if (lkPlatformIs(PlatformType.android)) {
    await Native.setAndroidSpeakerphoneOn(preferred, force: _forceSpeakerOutput);
  }
}