@capgo/native-audio 8.2.11 → 8.2.13

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