@@ -83,9 +83,9 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
8383
8484 private func setupAudioSession( ) {
8585 do {
86+ // Only set the category without immediately activating/deactivating
8687 try self . session. setCategory ( AVAudioSession . Category. playback, options: . mixWithOthers)
87- try self . session. setActive ( true )
88- try self . session. setActive ( false )
88+ // Don't activate/deactivate in setup - we'll do this explicitly when needed
8989 } catch {
9090 print ( " Failed to setup audio session: \( error) " )
9191 }
@@ -135,18 +135,18 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
135135
136136 // Use a single audio session configuration block for better atomicity
137137 do {
138- try self . session. setActive ( true )
139-
138+ // Set category first
140139 if focus {
141140 try self . session. setCategory ( AVAudioSession . Category. playback, options: . duckOthers)
142141 } else if !ignoreSilent {
143142 try self . session. setCategory ( AVAudioSession . Category. ambient, options: focus ? . duckOthers : . mixWithOthers)
144143 } else {
145144 try self . session. setCategory ( AVAudioSession . Category. playback, options: . mixWithOthers)
146145 }
147-
148- if !background {
149- try self . session. setActive ( false )
146+
147+ // Only activate if needed (background mode)
148+ if background {
149+ try self . session. setActive ( true )
150150 }
151151
152152 } catch {
@@ -175,22 +175,56 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
175175
176176 func activateSession( ) {
177177 do {
178- try self . session. setActive ( true )
178+ // Only activate if not already active
179+ if !session. isOtherAudioPlaying {
180+ try self . session. setActive ( true )
181+ }
179182 } catch {
180183 print ( " Failed to set session active: \( error) " )
181184 }
182185 }
183186
184187 func endSession( ) {
185188 do {
186- try self . session. setActive ( false , options: . notifyOthersOnDeactivation)
189+ // Check if any audio assets are still playing before deactivating
190+ let hasPlayingAssets = audioQueue. sync {
191+ return self . audioList. values. contains { asset in
192+ if let audioAsset = asset as? AudioAsset {
193+ return audioAsset. isPlaying ( )
194+ }
195+ return false
196+ }
197+ }
198+
199+ // Only deactivate if no assets are playing
200+ if !hasPlayingAssets {
201+ try self . session. setActive ( false , options: . notifyOthersOnDeactivation)
202+ }
187203 } catch {
188204 print ( " Failed to deactivate audio session: \( error) " )
189205 }
190206 }
191207
192208 public func audioPlayerDidFinishPlaying( _ player: AVAudioPlayer , successfully flag: Bool ) {
193- self . endSession ( )
209+ // Don't immediately end the session here, as other players might still be active
210+ // Instead, check if all players are done
211+ audioQueue. async { [ weak self] in
212+ guard let self = self else { return }
213+
214+ // Avoid recursive calls by checking if the asset is still in the list
215+ let hasPlayingAssets = self . audioList. values. contains { asset in
216+ if let audioAsset = asset as? AudioAsset {
217+ // Check if the asset has any playing channels other than the one that just finished
218+ return audioAsset. channels. contains { $0 != player && $0. isPlaying }
219+ }
220+ return false
221+ }
222+
223+ // Only end the session if no more assets are playing
224+ if !hasPlayingAssets {
225+ self . endSession ( )
226+ }
227+ }
194228 }
195229
196230 @objc func play( _ call: CAPPluginCall ) {
0 commit comments