@capgo/native-audio 7.3.10 → 7.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,14 +86,19 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
86
86
  }
87
87
 
88
88
  deinit {
89
- stopCurrentTimeUpdates()
90
- stopFadeTimer()
89
+ currentTimeTimer?.invalidate()
90
+ currentTimeTimer = nil
91
+
92
+ fadeTimer?.invalidate()
93
+ fadeTimer = nil
94
+
91
95
  // Clean up any players that might still be playing
92
96
  for player in channels {
93
97
  if player.isPlaying {
94
98
  player.stop()
95
99
  }
96
100
  }
101
+ channels = []
97
102
  }
98
103
 
99
104
  /**
@@ -153,6 +158,9 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
153
158
  * - delay: Delay before playback in seconds
154
159
  */
155
160
  func play(time: TimeInterval, delay: TimeInterval) {
161
+ stopCurrentTimeUpdates()
162
+ stopFadeTimer()
163
+
156
164
  owner?.executeOnAudioQueue { [self] in
157
165
  guard !channels.isEmpty else { return }
158
166
 
@@ -161,6 +169,9 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
161
169
  playIndex = 0
162
170
  }
163
171
 
172
+ // Ensure the audio session is active before playing
173
+ owner?.activateSession()
174
+
164
175
  let player = channels[playIndex]
165
176
  // Ensure time is within valid range
166
177
  let validTime = min(max(time, 0), player.duration)
@@ -175,6 +186,7 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
175
186
  } else {
176
187
  player.play()
177
188
  }
189
+
178
190
  playIndex = (playIndex + 1) % channels.count
179
191
  startCurrentTimeUpdates()
180
192
  }
@@ -368,11 +380,18 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
368
380
  }
369
381
  }
370
382
 
383
+ /**
384
+ * AVAudioPlayerDelegate method called when playback finishes
385
+ */
371
386
  public func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
372
387
  owner?.executeOnAudioQueue { [self] in
373
388
  self.owner?.notifyListeners("complete", data: [
374
389
  "assetId": self.assetId
375
390
  ])
391
+
392
+ // Notify the owner that this player finished
393
+ // The owner will check if any other assets are still playing
394
+ owner?.audioPlayerDidFinishPlaying(player, successfully: flag)
376
395
  }
377
396
  }
378
397
 
@@ -83,9 +83,9 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
83
83
 
84
84
  private func setupAudioSession() {
85
85
  do {
86
+ // Only set the category without immediately activating/deactivating
86
87
  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
89
89
  } catch {
90
90
  print("Failed to setup audio session: \(error)")
91
91
  }
@@ -135,8 +135,7 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
135
135
 
136
136
  // Use a single audio session configuration block for better atomicity
137
137
  do {
138
- try self.session.setActive(true)
139
-
138
+ // Set category first
140
139
  if focus {
141
140
  try self.session.setCategory(AVAudioSession.Category.playback, options: .duckOthers)
142
141
  } else if !ignoreSilent {
@@ -144,9 +143,10 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
144
143
  } else {
145
144
  try self.session.setCategory(AVAudioSession.Category.playback, options: .mixWithOthers)
146
145
  }
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)
150
150
  }
151
151
 
152
152
  } catch {
@@ -175,7 +175,10 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
175
175
 
176
176
  func activateSession() {
177
177
  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
+ }
179
182
  } catch {
180
183
  print("Failed to set session active: \(error)")
181
184
  }
@@ -183,14 +186,45 @@ public class NativeAudio: CAPPlugin, AVAudioPlayerDelegate, CAPBridgedPlugin {
183
186
 
184
187
  func endSession() {
185
188
  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
+ }
187
203
  } catch {
188
204
  print("Failed to deactivate audio session: \(error)")
189
205
  }
190
206
  }
191
207
 
192
208
  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
+ }
194
228
  }
195
229
 
196
230
  @objc func play(_ call: CAPPluginCall) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/native-audio",
3
- "version": "7.3.10",
3
+ "version": "7.3.12",
4
4
  "description": "A native plugin for native audio engine",
5
5
  "license": "MIT",
6
6
  "main": "dist/plugin.cjs.js",