@capgo/native-audio 8.2.12 → 8.2.14

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.
package/dist/plugin.js CHANGED
@@ -14,21 +14,62 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
14
14
  class NativeAudioWeb extends core.WebPlugin {
15
15
  constructor() {
16
16
  super();
17
+ this.debugMode = false;
18
+ this.currentTimeIntervals = new Map();
19
+ this.zeroVolume = 0.0001;
17
20
  }
18
21
  async resume(options) {
22
+ var _a, _b;
19
23
  const audio = this.getAudioAsset(options.assetId).audio;
24
+ const data = this.getAudioAssetData(options.assetId);
25
+ const targetVolume = (_b = (_a = data.volumeBeforePause) !== null && _a !== void 0 ? _a : data.volume) !== null && _b !== void 0 ? _b : 1;
26
+ if (options.fadeIn) {
27
+ const fadeDuration = options.fadeInDuration || NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
28
+ this.doFadeIn(audio, fadeDuration, targetVolume);
29
+ }
30
+ else if (audio.volume <= this.zeroVolume) {
31
+ audio.volume = targetVolume;
32
+ this.setGainNodeVolume(audio, targetVolume);
33
+ }
34
+ this.clearFadeOutToStopTimer(options.assetId);
35
+ return this.doResume(options.assetId);
36
+ }
37
+ async doResume(assetId) {
38
+ const audio = this.getAudioAsset(assetId).audio;
39
+ this.startCurrentTimeUpdates(assetId);
20
40
  if (audio.paused) {
21
41
  return audio.play();
22
42
  }
23
43
  }
24
44
  async pause(options) {
45
+ var _a;
25
46
  const audio = this.getAudioAsset(options.assetId).audio;
26
- return audio.pause();
47
+ this.cancelGainNodeRamp(audio);
48
+ const data = this.getAudioAssetData(options.assetId);
49
+ data.volumeBeforePause = (_a = data.volume) !== null && _a !== void 0 ? _a : audio.volume;
50
+ this.setAudioAssetData(options.assetId, data);
51
+ if (!audio.paused && options.fadeOut) {
52
+ const fadeOutDuration = options.fadeOutDuration || NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
53
+ this.doFadeOut(audio, fadeOutDuration);
54
+ data.fadeOutToStopTimer = window.setTimeout(() => {
55
+ this.doPause(options.assetId).catch(() => {
56
+ // no-op
57
+ });
58
+ }, fadeOutDuration * 1000);
59
+ this.setAudioAssetData(options.assetId, data);
60
+ return;
61
+ }
62
+ return this.doPause(options.assetId);
63
+ }
64
+ async doPause(assetId) {
65
+ const audio = this.getAudioAsset(assetId).audio;
66
+ this.clearFadeOutToStopTimer(assetId);
67
+ this.stopCurrentTimeUpdates(assetId);
68
+ audio.pause();
27
69
  }
28
70
  async setCurrentTime(options) {
29
71
  const audio = this.getAudioAsset(options.assetId).audio;
30
72
  audio.currentTime = options.time;
31
- return;
32
73
  }
33
74
  async getCurrentTime(options) {
34
75
  const audio = this.getAudioAsset(options.assetId).audio;
@@ -44,6 +85,12 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
44
85
  }
45
86
  return { duration: audio.duration };
46
87
  }
88
+ async setDebugMode(options) {
89
+ this.debugMode = options.enabled;
90
+ if (this.debugMode) {
91
+ this.logInfo('Debug mode enabled');
92
+ }
93
+ }
47
94
  async configure(options) {
48
95
  throw `configure is not supported for web: ${JSON.stringify(options)}`;
49
96
  }
@@ -51,55 +98,70 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
51
98
  try {
52
99
  return { found: !!this.getAudioAsset(options.assetId) };
53
100
  }
54
- catch (e) {
101
+ catch (_a) {
55
102
  return { found: false };
56
103
  }
57
104
  }
58
105
  async preload(options) {
59
106
  var _a;
107
+ this.logInfo(`Preloading audio asset with options: ${JSON.stringify(options)}`);
60
108
  if (NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(options.assetId)) {
61
109
  throw 'AssetId already exists. Unload first if like to change!';
62
110
  }
63
111
  if (!((_a = options.assetPath) === null || _a === void 0 ? void 0 : _a.length)) {
64
112
  throw 'no assetPath provided';
65
113
  }
66
- if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {
67
- const slashPrefix = options.assetPath.startsWith('/') ? '' : '/';
68
- options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;
69
- }
70
- const audio = new Audio(options.assetPath);
71
- audio.autoplay = false;
72
- audio.loop = false;
73
- audio.preload = 'auto';
74
- if (options.volume) {
75
- audio.volume = options.volume;
76
- }
77
- NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));
114
+ NativeAudioWeb.AUDIO_PRELOAD_OPTIONS_MAP.set(options.assetId, options);
115
+ await new Promise((resolve, reject) => {
116
+ var _a;
117
+ if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {
118
+ const slashPrefix = options.assetPath.startsWith('/') ? '' : '/';
119
+ options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;
120
+ }
121
+ const audio = document.createElement('audio');
122
+ audio.id = options.assetId;
123
+ audio.crossOrigin = 'anonymous';
124
+ audio.src = options.assetPath;
125
+ audio.autoplay = false;
126
+ audio.loop = false;
127
+ audio.preload = 'metadata';
128
+ audio.addEventListener('loadedmetadata', () => {
129
+ resolve();
130
+ });
131
+ audio.addEventListener('error', (errEvt) => {
132
+ this.logError(`Error loading audio file: ${options.assetPath}, error: ${String(errEvt)}`);
133
+ reject('Error loading audio file');
134
+ });
135
+ const data = this.getAudioAssetData(options.assetId);
136
+ if (typeof options.volume === 'number') {
137
+ audio.volume = options.volume;
138
+ data.volume = options.volume;
139
+ }
140
+ else {
141
+ data.volume = audio.volume;
142
+ }
143
+ NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));
144
+ this.setAudioAssetData(options.assetId, data);
145
+ this.setGainNodeVolume(audio, (_a = data.volume) !== null && _a !== void 0 ? _a : 1);
146
+ });
78
147
  }
79
148
  async playOnce(options) {
80
149
  var _a;
81
- // Generate a unique temporary asset ID
82
150
  const assetId = `playOnce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
83
151
  NativeAudioWeb.playOnceAssets.add(assetId);
84
- const autoPlay = options.autoPlay !== false; // Default to true
152
+ const autoPlay = options.autoPlay !== false;
85
153
  const deleteAfterPlay = (_a = options.deleteAfterPlay) !== null && _a !== void 0 ? _a : false;
86
154
  try {
87
- // Preload the asset
88
155
  await this.preload({
89
156
  assetId,
90
157
  assetPath: options.assetPath,
91
158
  volume: options.volume,
92
159
  isUrl: options.isUrl,
93
160
  });
94
- // Set up automatic cleanup on completion
95
- const audio = this.getAudioAsset(assetId).audio;
96
161
  const cleanupHandler = async () => {
97
162
  try {
98
- // Unload the asset
99
163
  await this.unload({ assetId });
100
164
  NativeAudioWeb.playOnceAssets.delete(assetId);
101
- // Delete file if requested (Web can't actually delete files from disk)
102
- // This is a no-op on web, but we keep the interface consistent
103
165
  if (deleteAfterPlay) {
104
166
  console.warn('[NativeAudio] deleteAfterPlay is not supported on web platform. File deletion is ignored.');
105
167
  }
@@ -108,21 +170,23 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
108
170
  console.error('[NativeAudio] Error during playOnce cleanup:', error);
109
171
  }
110
172
  };
111
- audio.addEventListener('ended', cleanupHandler, { once: true });
112
- // Handle errors during playback - cleanup if play fails
113
- audio.addEventListener('error', () => {
173
+ if (autoPlay) {
174
+ await this.doPlay({ assetId, volume: options.volume }, false);
175
+ }
176
+ const currentAudio = this.getAudioAsset(assetId).audio;
177
+ currentAudio.addEventListener('ended', () => {
178
+ cleanupHandler().catch((error) => {
179
+ console.error('[NativeAudio] Error during ended cleanup:', error);
180
+ });
181
+ }, { once: true });
182
+ currentAudio.addEventListener('error', () => {
114
183
  cleanupHandler().catch((error) => {
115
184
  console.error('[NativeAudio] Error during error cleanup:', error);
116
185
  });
117
186
  }, { once: true });
118
- // Auto-play if requested
119
- if (autoPlay) {
120
- await this.play({ assetId });
121
- }
122
187
  return { assetId };
123
188
  }
124
189
  catch (error) {
125
- // Cleanup on failure
126
190
  try {
127
191
  await this.unload({ assetId });
128
192
  NativeAudioWeb.playOnceAssets.delete(assetId);
@@ -134,43 +198,196 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
134
198
  }
135
199
  }
136
200
  onEnded(assetId) {
201
+ this.logDebug(`Playback ended for assetId: ${assetId}`);
137
202
  this.notifyListeners('complete', { assetId });
138
203
  }
139
204
  async play(options) {
205
+ this.logInfo(`Playing audio asset with options: ${JSON.stringify(options)}`);
206
+ this.clearFadeOutToStopTimer(options.assetId);
207
+ const { delay = 0 } = options;
208
+ if (delay > 0) {
209
+ const data = this.getAudioAssetData(options.assetId);
210
+ data.startTimer = window.setTimeout(() => {
211
+ this.doPlay(options).catch((error) => {
212
+ this.logError(`Delayed play failed: ${String(error)}`);
213
+ });
214
+ data.startTimer = undefined;
215
+ this.setAudioAssetData(options.assetId, data);
216
+ }, delay * 1000);
217
+ this.setAudioAssetData(options.assetId, data);
218
+ return;
219
+ }
220
+ await this.doPlay(options);
221
+ }
222
+ async doPlay(options, recreateAudioElement = true) {
140
223
  const { assetId, time = 0 } = options;
224
+ if (!NativeAudioWeb.AUDIO_PRELOAD_OPTIONS_MAP.has(assetId)) {
225
+ throw `no asset for assetId "${assetId}" available. Call preload first!`;
226
+ }
227
+ if (recreateAudioElement) {
228
+ const preloadOptions = NativeAudioWeb.AUDIO_PRELOAD_OPTIONS_MAP.get(assetId);
229
+ await this.unload({ assetId });
230
+ await this.preload(preloadOptions);
231
+ }
141
232
  const audio = this.getAudioAsset(assetId).audio;
142
- await this.stop(options);
233
+ audio.id = assetId;
143
234
  audio.loop = false;
144
235
  audio.currentTime = time;
145
236
  audio.addEventListener('ended', () => this.onEnded(assetId), {
146
237
  once: true,
147
238
  });
148
- return audio.play();
239
+ const data = this.getAudioAssetData(assetId);
240
+ if (typeof options.volume === 'number') {
241
+ audio.volume = options.volume;
242
+ data.volume = options.volume;
243
+ this.setGainNodeVolume(audio, options.volume);
244
+ }
245
+ else if (typeof data.volume !== 'number') {
246
+ data.volume = audio.volume;
247
+ }
248
+ await audio.play();
249
+ this.startCurrentTimeUpdates(assetId);
250
+ if (options.fadeIn) {
251
+ this.logDebug(`Fading in audio asset with assetId: ${assetId}`);
252
+ const fadeDuration = options.fadeInDuration || NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
253
+ this.doFadeIn(audio, fadeDuration);
254
+ }
255
+ if (options.fadeOut && !Number.isNaN(audio.duration) && Number.isFinite(audio.duration)) {
256
+ this.logDebug(`Scheduling fade out for audio asset with assetId: ${assetId}`);
257
+ const fadeOutDuration = options.fadeOutDuration || NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
258
+ const fadeOutStartTime = options.fadeOutStartTime || audio.duration - fadeOutDuration;
259
+ data.fadeOut = true;
260
+ data.fadeOutStartTime = fadeOutStartTime;
261
+ data.fadeOutDuration = fadeOutDuration;
262
+ }
263
+ this.setAudioAssetData(assetId, data);
264
+ }
265
+ doFadeIn(audio, fadeDuration, targetVolume) {
266
+ var _a;
267
+ const data = this.getAudioAssetData(audio.id);
268
+ this.setGainNodeVolume(audio, this.zeroVolume);
269
+ const fadeToVolume = (_a = targetVolume !== null && targetVolume !== void 0 ? targetVolume : data.volume) !== null && _a !== void 0 ? _a : 1;
270
+ this.linearRampGainNodeVolume(audio, fadeToVolume, fadeDuration);
271
+ data.fadeInTimer = window.setTimeout(() => {
272
+ data.fadeInTimer = undefined;
273
+ this.setAudioAssetData(audio.id, data);
274
+ }, fadeDuration * 1000);
275
+ this.setAudioAssetData(audio.id, data);
276
+ }
277
+ doFadeOut(audio, fadeDuration) {
278
+ this.linearRampGainNodeVolume(audio, this.zeroVolume, fadeDuration);
149
279
  }
150
280
  async loop(options) {
281
+ this.logInfo(`Looping audio asset with options: ${JSON.stringify(options)}`);
151
282
  const audio = this.getAudioAsset(options.assetId).audio;
152
- await this.stop(options);
283
+ this.reset(audio);
153
284
  audio.loop = true;
285
+ this.startCurrentTimeUpdates(options.assetId);
154
286
  return audio.play();
155
287
  }
156
288
  async stop(options) {
289
+ this.logInfo(`Stopping audio asset with options: ${JSON.stringify(options)}`);
157
290
  const audio = this.getAudioAsset(options.assetId).audio;
291
+ const data = this.getAudioAssetData(options.assetId);
292
+ this.clearFadeOutToStopTimer(options.assetId);
293
+ this.cancelGainNodeRamp(audio);
294
+ if (!audio.paused && options.fadeOut) {
295
+ const fadeDuration = options.fadeOutDuration || NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
296
+ this.doFadeOut(audio, fadeDuration);
297
+ data.fadeOutToStopTimer = window.setTimeout(() => {
298
+ this.doStop(audio, options);
299
+ }, fadeDuration * 1000);
300
+ this.setAudioAssetData(options.assetId, data);
301
+ return;
302
+ }
303
+ this.doStop(audio, options);
304
+ }
305
+ doStop(audio, options) {
158
306
  audio.pause();
159
- audio.loop = false;
307
+ this.onEnded(options.assetId);
308
+ this.reset(audio);
309
+ }
310
+ reset(audio) {
311
+ var _a;
160
312
  audio.currentTime = 0;
313
+ for (const [assetId, asset] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.entries()) {
314
+ if (asset.audio === audio) {
315
+ this.stopCurrentTimeUpdates(assetId);
316
+ this.clearFadeOutToStopTimer(assetId);
317
+ this.clearStartTimer(assetId);
318
+ this.cancelGainNodeRamp(audio);
319
+ const data = this.getAudioAssetData(assetId);
320
+ const initialVolume = (_a = data.volume) !== null && _a !== void 0 ? _a : 1;
321
+ this.setGainNodeVolume(audio, initialVolume);
322
+ this.setAudioAssetData(assetId, data);
323
+ break;
324
+ }
325
+ }
326
+ }
327
+ clearFadeOutToStopTimer(assetId) {
328
+ const data = this.getAudioAssetData(assetId);
329
+ if (data.fadeOutToStopTimer) {
330
+ clearTimeout(data.fadeOutToStopTimer);
331
+ data.fadeOutToStopTimer = undefined;
332
+ this.setAudioAssetData(assetId, data);
333
+ }
334
+ }
335
+ clearStartTimer(assetId) {
336
+ const data = this.getAudioAssetData(assetId);
337
+ if (data.startTimer) {
338
+ clearTimeout(data.startTimer);
339
+ data.startTimer = undefined;
340
+ this.setAudioAssetData(assetId, data);
341
+ }
161
342
  }
162
343
  async unload(options) {
163
- await this.stop(options);
344
+ this.logInfo(`Unloading audio asset with options: ${JSON.stringify(options)}`);
345
+ const audio = this.getAudioAsset(options.assetId).audio;
346
+ this.reset(audio);
164
347
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.delete(options.assetId);
348
+ NativeAudioWeb.AUDIO_PRELOAD_OPTIONS_MAP.delete(options.assetId);
349
+ NativeAudioWeb.AUDIO_DATA_MAP.delete(options.assetId);
350
+ this.cleanupAudioContext(audio);
351
+ }
352
+ cleanupAudioContext(audio) {
353
+ const gainNode = NativeAudioWeb.GAIN_NODE_MAP.get(audio);
354
+ if (gainNode) {
355
+ gainNode.disconnect();
356
+ NativeAudioWeb.GAIN_NODE_MAP.delete(audio);
357
+ }
358
+ const sourceNode = NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP.get(audio);
359
+ if (sourceNode) {
360
+ sourceNode.disconnect();
361
+ NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP.delete(audio);
362
+ }
363
+ const audioContext = NativeAudioWeb.AUDIO_CONTEXT_MAP.get(audio);
364
+ if (audioContext) {
365
+ audioContext.close().catch(() => {
366
+ // no-op
367
+ });
368
+ NativeAudioWeb.AUDIO_CONTEXT_MAP.delete(audio);
369
+ }
165
370
  }
166
371
  async setVolume(options) {
372
+ this.logInfo(`Setting volume for audio asset with options: ${JSON.stringify(options)}`);
167
373
  if (typeof (options === null || options === void 0 ? void 0 : options.volume) !== 'number') {
168
374
  throw 'no volume provided';
169
375
  }
376
+ const { volume, duration = 0 } = options;
377
+ const data = this.getAudioAssetData(options.assetId);
378
+ data.volume = volume;
379
+ this.setAudioAssetData(options.assetId, data);
170
380
  const audio = this.getAudioAsset(options.assetId).audio;
171
- audio.volume = options.volume;
381
+ this.cancelGainNodeRamp(audio);
382
+ if (duration > 0) {
383
+ this.exponentialRampGainNodeVolume(audio, volume, duration);
384
+ return;
385
+ }
386
+ audio.volume = volume;
387
+ this.setGainNodeVolume(audio, volume);
172
388
  }
173
389
  async setRate(options) {
390
+ this.logInfo(`Setting playback rate for audio asset with options: ${JSON.stringify(options)}`);
174
391
  if (typeof (options === null || options === void 0 ? void 0 : options.rate) !== 'number') {
175
392
  throw 'no rate provided';
176
393
  }
@@ -182,8 +399,7 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
182
399
  return { isPlaying: !audio.paused };
183
400
  }
184
401
  async clearCache() {
185
- // Web audio doesn't have a persistent cache to clear
186
- return;
402
+ this.logWarning('clearCache is not supported for web. No cache to clear.');
187
403
  }
188
404
  getAudioAsset(assetId) {
189
405
  this.checkAssetId(assetId);
@@ -200,19 +416,148 @@ var capacitorCapacitorNativeAudio = (function (exports, core) {
200
416
  throw 'no assetId provided';
201
417
  }
202
418
  }
419
+ getOrCreateAudioContext(audio) {
420
+ if (NativeAudioWeb.AUDIO_CONTEXT_MAP.has(audio)) {
421
+ return NativeAudioWeb.AUDIO_CONTEXT_MAP.get(audio);
422
+ }
423
+ const audioContext = new AudioContext();
424
+ NativeAudioWeb.AUDIO_CONTEXT_MAP.set(audio, audioContext);
425
+ return audioContext;
426
+ }
427
+ getOrCreateMediaElementSource(audioContext, audio) {
428
+ if (NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP.has(audio)) {
429
+ return NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP.get(audio);
430
+ }
431
+ const sourceNode = audioContext.createMediaElementSource(audio);
432
+ NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP.set(audio, sourceNode);
433
+ return sourceNode;
434
+ }
435
+ getOrCreateGainNode(audio, track) {
436
+ const audioContext = this.getOrCreateAudioContext(audio);
437
+ if (NativeAudioWeb.GAIN_NODE_MAP.has(audio)) {
438
+ return NativeAudioWeb.GAIN_NODE_MAP.get(audio);
439
+ }
440
+ const gainNode = audioContext.createGain();
441
+ track.connect(gainNode).connect(audioContext.destination);
442
+ NativeAudioWeb.GAIN_NODE_MAP.set(audio, gainNode);
443
+ return gainNode;
444
+ }
445
+ setGainNodeVolume(audio, volume, time) {
446
+ const audioContext = this.getOrCreateAudioContext(audio);
447
+ const track = this.getOrCreateMediaElementSource(audioContext, audio);
448
+ const gainNode = this.getOrCreateGainNode(audio, track);
449
+ if (time !== undefined) {
450
+ gainNode.gain.setValueAtTime(volume, time);
451
+ }
452
+ else {
453
+ gainNode.gain.setValueAtTime(volume, audioContext.currentTime);
454
+ }
455
+ }
456
+ exponentialRampGainNodeVolume(audio, volume, duration) {
457
+ const audioContext = this.getOrCreateAudioContext(audio);
458
+ const track = this.getOrCreateMediaElementSource(audioContext, audio);
459
+ const gainNode = this.getOrCreateGainNode(audio, track);
460
+ const adjustedVolume = volume < this.zeroVolume ? this.zeroVolume : volume;
461
+ gainNode.gain.exponentialRampToValueAtTime(adjustedVolume, audioContext.currentTime + duration);
462
+ }
463
+ linearRampGainNodeVolume(audio, volume, duration) {
464
+ const audioContext = this.getOrCreateAudioContext(audio);
465
+ const track = this.getOrCreateMediaElementSource(audioContext, audio);
466
+ const gainNode = this.getOrCreateGainNode(audio, track);
467
+ gainNode.gain.linearRampToValueAtTime(volume, audioContext.currentTime + duration);
468
+ }
469
+ cancelGainNodeRamp(audio) {
470
+ const gainNode = NativeAudioWeb.GAIN_NODE_MAP.get(audio);
471
+ if (gainNode) {
472
+ gainNode.gain.cancelScheduledValues(0);
473
+ }
474
+ }
475
+ startCurrentTimeUpdates(assetId) {
476
+ this.stopCurrentTimeUpdates(assetId);
477
+ const audio = this.getAudioAsset(assetId).audio;
478
+ const intervalId = window.setInterval(() => {
479
+ var _a;
480
+ if (!audio.paused) {
481
+ const currentTime = Math.round(audio.currentTime * 10) / 10;
482
+ this.notifyListeners('currentTime', { assetId, currentTime });
483
+ this.logDebug(`Current time update for assetId: ${assetId}, currentTime: ${currentTime}`);
484
+ const data = this.getAudioAssetData(assetId);
485
+ if (data.fadeOut && typeof data.fadeOutStartTime === 'number' && currentTime >= data.fadeOutStartTime) {
486
+ this.cancelGainNodeRamp(audio);
487
+ const fadeOutDuration = (_a = data.fadeOutDuration) !== null && _a !== void 0 ? _a : NativeAudioWeb.DEFAULT_FADE_DURATION_SEC;
488
+ this.doFadeOut(audio, fadeOutDuration);
489
+ data.fadeOut = false;
490
+ this.setAudioAssetData(assetId, data);
491
+ }
492
+ }
493
+ else {
494
+ this.stopCurrentTimeUpdates(assetId);
495
+ }
496
+ }, NativeAudioWeb.CURRENT_TIME_UPDATE_INTERVAL);
497
+ this.currentTimeIntervals.set(assetId, intervalId);
498
+ }
499
+ stopCurrentTimeUpdates(assetId) {
500
+ if (assetId) {
501
+ const intervalId = this.currentTimeIntervals.get(assetId);
502
+ if (intervalId) {
503
+ clearInterval(intervalId);
504
+ this.currentTimeIntervals.delete(assetId);
505
+ }
506
+ return;
507
+ }
508
+ for (const intervalId of this.currentTimeIntervals.values()) {
509
+ clearInterval(intervalId);
510
+ }
511
+ this.currentTimeIntervals.clear();
512
+ }
513
+ getAudioAssetData(assetId) {
514
+ return NativeAudioWeb.AUDIO_DATA_MAP.get(assetId) || {};
515
+ }
516
+ setAudioAssetData(assetId, data) {
517
+ const currentData = NativeAudioWeb.AUDIO_DATA_MAP.get(assetId) || {};
518
+ const newData = Object.assign(Object.assign({}, currentData), data);
519
+ NativeAudioWeb.AUDIO_DATA_MAP.set(assetId, newData);
520
+ }
521
+ logError(message) {
522
+ if (!this.debugMode)
523
+ return;
524
+ console.error(`${NativeAudioWeb.LOG_TAG} Error: ${message}`);
525
+ }
526
+ logWarning(message) {
527
+ if (!this.debugMode)
528
+ return;
529
+ console.warn(`${NativeAudioWeb.LOG_TAG} Warning: ${message}`);
530
+ }
531
+ logInfo(message) {
532
+ if (!this.debugMode)
533
+ return;
534
+ console.info(`${NativeAudioWeb.LOG_TAG} Info: ${message}`);
535
+ }
536
+ logDebug(message) {
537
+ if (!this.debugMode)
538
+ return;
539
+ console.debug(`${NativeAudioWeb.LOG_TAG} Debug: ${message}`);
540
+ }
203
541
  async getPluginVersion() {
204
542
  return { version: 'web' };
205
543
  }
206
544
  async deinitPlugin() {
207
- // Stop and unload all audio assets
208
545
  for (const [assetId] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID) {
209
546
  await this.unload({ assetId });
210
547
  }
211
- return;
548
+ this.stopCurrentTimeUpdates();
212
549
  }
213
550
  }
551
+ NativeAudioWeb.LOG_TAG = '[NativeAudioWeb]';
214
552
  NativeAudioWeb.FILE_LOCATION = '';
553
+ NativeAudioWeb.DEFAULT_FADE_DURATION_SEC = 1;
554
+ NativeAudioWeb.CURRENT_TIME_UPDATE_INTERVAL = 100;
555
+ NativeAudioWeb.AUDIO_PRELOAD_OPTIONS_MAP = new Map();
556
+ NativeAudioWeb.AUDIO_DATA_MAP = new Map();
215
557
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID = new Map();
558
+ NativeAudioWeb.AUDIO_CONTEXT_MAP = new Map();
559
+ NativeAudioWeb.MEDIA_ELEMENT_SOURCE_MAP = new Map();
560
+ NativeAudioWeb.GAIN_NODE_MAP = new Map();
216
561
  NativeAudioWeb.playOnceAssets = new Set();
217
562
  new NativeAudioWeb();
218
563