@capgo/native-audio 7.3.10 → 7.3.11

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.
@@ -153,6 +153,9 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
153
153
  * - delay: Delay before playback in seconds
154
154
  */
155
155
  func play(time: TimeInterval, delay: TimeInterval) {
156
+ stopCurrentTimeUpdates()
157
+ stopFadeTimer()
158
+
156
159
  owner?.executeOnAudioQueue { [self] in
157
160
  guard !channels.isEmpty else { return }
158
161
 
@@ -161,6 +164,9 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
161
164
  playIndex = 0
162
165
  }
163
166
 
167
+ // Ensure the audio session is active before playing
168
+ owner?.activateSession()
169
+
164
170
  let player = channels[playIndex]
165
171
  // Ensure time is within valid range
166
172
  let validTime = min(max(time, 0), player.duration)
@@ -175,6 +181,7 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
175
181
  } else {
176
182
  player.play()
177
183
  }
184
+
178
185
  playIndex = (playIndex + 1) % channels.count
179
186
  startCurrentTimeUpdates()
180
187
  }
@@ -368,11 +375,18 @@ public class AudioAsset: NSObject, AVAudioPlayerDelegate {
368
375
  }
369
376
  }
370
377
 
378
+ /**
379
+ * AVAudioPlayerDelegate method called when playback finishes
380
+ */
371
381
  public func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
372
382
  owner?.executeOnAudioQueue { [self] in
373
383
  self.owner?.notifyListeners("complete", data: [
374
384
  "assetId": self.assetId
375
385
  ])
386
+
387
+ // Notify the owner that this player finished
388
+ // The owner will check if any other assets are still playing
389
+ owner?.audioPlayerDidFinishPlaying(player, successfully: flag)
376
390
  }
377
391
  }
378
392
 
@@ -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.11",
4
4
  "description": "A native plugin for native audio engine",
5
5
  "license": "MIT",
6
6
  "main": "dist/plugin.cjs.js",