Skip to content

Disconnect from LiveKit server triggers microphone permission prompt on iOS #239

Description

@russell-works

After disconnecting from the LiveKit server, a system microphone permission prompt appears. I noticed this only happens if the app subscribes to a remote audio track through. The app does not use the local microphone at all / does not publish a track.

This is an iOS app using LiveKit Swift 2.14.0. The issue also exists on 2.13.0. Downgrading to 2.12.1 resolves the issue

LLM findings

No clue if this is valid but the LLM thinks the below code is the issue, which appears to be recently added in #228:

  The problem line (audio_engine_device.mm:2799):

  // Step: Release AVAudioEngine
  if (state.prev.IsAnyEnabled() && !state.next.IsAnyEnabled()) {
      AVAudioInputNode* input_node = engine_device_.inputNode; // ← always accessed
      AVAudioOutputNode* output_node = engine_device_.outputNode;

      if (input_node != nil && input_node.audioUnit != nullptr) {
          AudioOutputUnitStop(input_node.audioUnit);
      }
      if (output_node != nil && output_node.audioUnit != nullptr) {
          AudioOutputUnitStop(output_node.audioUnit);
      }
  }

  The fix:

  if (state.prev.IsAnyEnabled() && !state.next.IsAnyEnabled()) {
      // Only access inputNode if input was actually enabled. For VP I/O, inputNode and
      // outputNode share the same AudioUnit, so stopping the output unit is sufficient.
      // Accessing inputNode unnecessarily triggers a microphone permission prompt on iOS.
      if (state.prev.IsInputEnabled()) {
          AVAudioInputNode* input_node = engine_device_.inputNode;
          if (input_node != nil && input_node.audioUnit != nullptr) {
              AudioOutputUnitStop(input_node.audioUnit);
          }
      }

      AVAudioOutputNode* output_node = engine_device_.outputNode;
      if (output_node != nil && output_node.audioUnit != nullptr) {
          AudioOutputUnitStop(output_node.audioUnit);
      }
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions