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