Skip to content

fix(ios): stop interrupting other apps' audio on play and fix session deactivation#894

Open
WYSIATI wants to merge 1 commit intozmxv:masterfrom
WYSIATI:fix/ios-audio-session-management
Open

fix(ios): stop interrupting other apps' audio on play and fix session deactivation#894
WYSIATI wants to merge 1 commit intozmxv:masterfrom
WYSIATI:fix/ios-audio-session-management

Conversation

@WYSIATI
Copy link

@WYSIATI WYSIATI commented Mar 22, 2026

Problem

Two iOS audio session issues that affect apps playing short sound effects while the user has background music (Spotify, Apple Music, etc.):

1. play() interrupts other apps' audio on every call

play() calls [[AVAudioSession sharedInstance] setActive:YES error:nil] on every invocation. Even when the app's audio category is configured with mixWithOthers, this per-play activation triggers iOS audio route reconfiguration that pauses other audio sessions.

Additionally, play() registers NSNotificationCenter observers for AVAudioSessionInterruptionNotification on every call without removing previous registrations. The audioSessionChangeObserver auto-resumes playback on InterruptionTypeEnded, causing unexpected sound replay after lock screen, phone calls, or Siri.

2. setActive(false) doesn't notify other apps to resume

setActive(false) calls [session setActive:NO error:nil] without the AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation flag. Without this flag, other apps are never notified they can resume playback — their audio stays paused permanently.

Fix

  1. Remove setActive:YES and observer registration from play(). Audio session lifecycle should be managed by the app via setCategory/setActive, not implicitly by the library on every play call. AVAudioPlayer.play activates the session implicitly when needed.

  2. Pass notifyOthersOnDeactivation in setActive(false). When active=false, use [session setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil] so other apps know they can resume.

Migration

Apps that relied on the implicit setActive:YES in play() should add an explicit call during setup:

Sound.setCategory('Playback', true); // Set category with mixWithOthers
Sound.setActive(true);               // Activate session once

Apps that relied on auto-resume after interruptions should implement their own AppState listener.

Related Issues

… deactivation

Two issues in the iOS audio session management:

1. play() called [session setActive:YES] on every invocation, which
   interrupts other apps' audio (Spotify, Apple Music, etc.) even when
   the category is configured with mixWithOthers. The per-play activation
   triggers iOS audio route reconfiguration that pauses other audio
   sessions. Apps should call setActive(true) once during setup instead.

   play() also registered NSNotificationCenter observers for
   AVAudioSessionInterruptionNotification on every call without
   removing previous registrations. The audioSessionChangeObserver
   auto-resumes playback on InterruptionTypeEnded, causing unexpected
   sound replay after lock screen, phone calls, or Siri activations.

   Fix: Remove setActive:YES and observer registration from play().
   Audio session lifecycle should be managed by the app, not the library.

2. setActive(false) called [session setActive:NO] without the
   AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation flag.
   Without this flag, other apps are never notified that they can
   resume playback, causing their audio to stay paused permanently
   after our session deactivates.

   Fix: Pass notifyOthersOnDeactivation when deactivating so other
   apps can resume their audio.

These issues affect any app that plays short sound effects (timers,
notifications, UI feedback) while the user has background music playing.

Refs: zmxv#762, zmxv#480, zmxv#419, zmxv#559
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant