@capgo/native-audio 8.0.1 → 8.1.0

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/docs.json CHANGED
@@ -73,6 +73,46 @@
73
73
  ],
74
74
  "slug": "preload"
75
75
  },
76
+ {
77
+ "name": "playOnce",
78
+ "signature": "(options: PlayOnceOptions) => Promise<PlayOnceResult>",
79
+ "parameters": [
80
+ {
81
+ "name": "options",
82
+ "docs": "",
83
+ "type": "PlayOnceOptions"
84
+ }
85
+ ],
86
+ "returns": "Promise<PlayOnceResult>",
87
+ "tags": [
88
+ {
89
+ "name": "example",
90
+ "text": "```typescript\n// Simple one-shot playback\nawait NativeAudio.playOnce({ assetPath: 'audio/notification.mp3' });\n\n// Play and delete the file after completion\nawait NativeAudio.playOnce({\n assetPath: 'file:///path/to/temp/audio.mp3',\n isUrl: true,\n deleteAfterPlay: true\n});\n\n// Get the assetId to control playback\nconst { assetId } = await NativeAudio.playOnce({\n assetPath: 'audio/long-track.mp3',\n autoPlay: true\n});\n// Later, you can stop it manually if needed\nawait NativeAudio.stop({ assetId });\n```"
91
+ },
92
+ {
93
+ "name": "since",
94
+ "text": "7.11.0"
95
+ },
96
+ {
97
+ "name": "param",
98
+ "text": "options"
99
+ },
100
+ {
101
+ "name": "link",
102
+ "text": "PlayOnceOptions}"
103
+ },
104
+ {
105
+ "name": "returns",
106
+ "text": "Object containing the generated assetId"
107
+ }
108
+ ],
109
+ "docs": "Play an audio file once with automatic cleanup\n\nMethod designed for simple, single-shot audio playback,\nsuch as notification sounds, UI feedback, or other short audio clips\nthat don't require manual state management.\n\n**Key Features:**\n- **Fire-and-forget**: No need to manually preload, play, stop, or unload\n- **Auto-cleanup**: Asset is automatically unloaded after playback completes\n- **Optional file deletion**: Can delete local files after playback (useful for temp files)\n- **Returns assetId**: Can still control playback if needed (pause, stop, etc.)\n\n**Use Cases:**\n- Notification sounds\n- UI sound effects (button clicks, alerts)\n- Short audio clips that play once\n- Temporary audio files that should be cleaned up\n\n**Comparison with regular play():**\n- `play()`: Requires manual preload, play, and unload steps\n- `playOnce()`: Handles everything automatically with a single call",
110
+ "complexTypes": [
111
+ "PlayOnceResult",
112
+ "PlayOnceOptions"
113
+ ],
114
+ "slug": "playonce"
115
+ },
76
116
  {
77
117
  "name": "isPreloaded",
78
118
  "signature": "(options: PreloadOptions) => Promise<{ found: boolean; }>",
@@ -780,6 +820,122 @@
780
820
  }
781
821
  ]
782
822
  },
823
+ {
824
+ "name": "PlayOnceResult",
825
+ "slug": "playonceresult",
826
+ "docs": "",
827
+ "tags": [],
828
+ "methods": [],
829
+ "properties": [
830
+ {
831
+ "name": "assetId",
832
+ "tags": [],
833
+ "docs": "The internally generated asset ID for this playback\nCan be used to control playback (pause, stop, etc.) before completion",
834
+ "complexTypes": [],
835
+ "type": "string"
836
+ }
837
+ ]
838
+ },
839
+ {
840
+ "name": "PlayOnceOptions",
841
+ "slug": "playonceoptions",
842
+ "docs": "",
843
+ "tags": [],
844
+ "methods": [],
845
+ "properties": [
846
+ {
847
+ "name": "assetPath",
848
+ "tags": [],
849
+ "docs": "Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)\nSupported formats:\n- MP3, WAV (all platforms)\n- M3U8/HLS streams (iOS and Android)",
850
+ "complexTypes": [],
851
+ "type": "string"
852
+ },
853
+ {
854
+ "name": "volume",
855
+ "tags": [
856
+ {
857
+ "text": "1.0",
858
+ "name": "default"
859
+ }
860
+ ],
861
+ "docs": "Volume of the audio, between 0.1 and 1.0",
862
+ "complexTypes": [],
863
+ "type": "number | undefined"
864
+ },
865
+ {
866
+ "name": "isUrl",
867
+ "tags": [
868
+ {
869
+ "text": "false",
870
+ "name": "default"
871
+ }
872
+ ],
873
+ "docs": "Is the audio file a URL, pass true if assetPath is a `file://` url\nor a streaming URL (m3u8)",
874
+ "complexTypes": [],
875
+ "type": "boolean | undefined"
876
+ },
877
+ {
878
+ "name": "autoPlay",
879
+ "tags": [
880
+ {
881
+ "text": "true",
882
+ "name": "default"
883
+ }
884
+ ],
885
+ "docs": "Automatically start playback after loading",
886
+ "complexTypes": [],
887
+ "type": "boolean | undefined"
888
+ },
889
+ {
890
+ "name": "deleteAfterPlay",
891
+ "tags": [
892
+ {
893
+ "text": "false",
894
+ "name": "default"
895
+ },
896
+ {
897
+ "text": "7.11.0",
898
+ "name": "since"
899
+ }
900
+ ],
901
+ "docs": "Delete the audio file from disk after playback completes\nOnly works for local files (file:// URLs), ignored for remote URLs",
902
+ "complexTypes": [],
903
+ "type": "boolean | undefined"
904
+ },
905
+ {
906
+ "name": "notificationMetadata",
907
+ "tags": [
908
+ {
909
+ "text": "NotificationMetadata *",
910
+ "name": "see"
911
+ },
912
+ {
913
+ "text": "7.10.0",
914
+ "name": "since"
915
+ }
916
+ ],
917
+ "docs": "Metadata to display in the notification center when audio is playing.\nOnly used when `showNotification: true` is set in `configure()`.\n\nSee {@link ConfigureOptions.showNotification} for important details about\nhow this affects audio mixing behavior on iOS.",
918
+ "complexTypes": [
919
+ "NotificationMetadata"
920
+ ],
921
+ "type": "NotificationMetadata"
922
+ },
923
+ {
924
+ "name": "headers",
925
+ "tags": [
926
+ {
927
+ "text": "7.10.0",
928
+ "name": "since"
929
+ }
930
+ ],
931
+ "docs": "Custom HTTP headers to include when fetching remote audio files.\nOnly used when isUrl is true and assetPath is a remote URL (http/https).\nExample: { 'x-api-key': 'abc123', 'Authorization': 'Bearer token' }",
932
+ "complexTypes": [
933
+ "Record"
934
+ ],
935
+ "type": "Record<string, string>"
936
+ }
937
+ ]
938
+ },
783
939
  {
784
940
  "name": "Assets",
785
941
  "slug": "assets",
@@ -114,6 +114,64 @@ export interface NotificationMetadata {
114
114
  */
115
115
  artworkUrl?: string;
116
116
  }
117
+ export interface PlayOnceOptions {
118
+ /**
119
+ * Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)
120
+ * Supported formats:
121
+ * - MP3, WAV (all platforms)
122
+ * - M3U8/HLS streams (iOS and Android)
123
+ */
124
+ assetPath: string;
125
+ /**
126
+ * Volume of the audio, between 0.1 and 1.0
127
+ * @default 1.0
128
+ */
129
+ volume?: number;
130
+ /**
131
+ * Is the audio file a URL, pass true if assetPath is a `file://` url
132
+ * or a streaming URL (m3u8)
133
+ * @default false
134
+ */
135
+ isUrl?: boolean;
136
+ /**
137
+ * Automatically start playback after loading
138
+ * @default true
139
+ */
140
+ autoPlay?: boolean;
141
+ /**
142
+ * Delete the audio file from disk after playback completes
143
+ * Only works for local files (file:// URLs), ignored for remote URLs
144
+ * @default false
145
+ * @since 7.11.0
146
+ */
147
+ deleteAfterPlay?: boolean;
148
+ /**
149
+ * Metadata to display in the notification center when audio is playing.
150
+ * Only used when `showNotification: true` is set in `configure()`.
151
+ *
152
+ * See {@link ConfigureOptions.showNotification} for important details about
153
+ * how this affects audio mixing behavior on iOS.
154
+ *
155
+ * @see NotificationMetadata
156
+ * @since 7.10.0
157
+ */
158
+ notificationMetadata?: NotificationMetadata;
159
+ /**
160
+ * Custom HTTP headers to include when fetching remote audio files.
161
+ * Only used when isUrl is true and assetPath is a remote URL (http/https).
162
+ * Example: { 'x-api-key': 'abc123', 'Authorization': 'Bearer token' }
163
+ *
164
+ * @since 7.10.0
165
+ */
166
+ headers?: Record<string, string>;
167
+ }
168
+ export interface PlayOnceResult {
169
+ /**
170
+ * The internally generated asset ID for this playback
171
+ * Can be used to control playback (pause, stop, etc.) before completion
172
+ */
173
+ assetId: string;
174
+ }
117
175
  export interface PreloadOptions {
118
176
  /**
119
177
  * Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)
@@ -186,6 +244,55 @@ export interface NativeAudio {
186
244
  * @returns
187
245
  */
188
246
  preload(options: PreloadOptions): Promise<void>;
247
+ /**
248
+ * Play an audio file once with automatic cleanup
249
+ *
250
+ * Method designed for simple, single-shot audio playback,
251
+ * such as notification sounds, UI feedback, or other short audio clips
252
+ * that don't require manual state management.
253
+ *
254
+ * **Key Features:**
255
+ * - **Fire-and-forget**: No need to manually preload, play, stop, or unload
256
+ * - **Auto-cleanup**: Asset is automatically unloaded after playback completes
257
+ * - **Optional file deletion**: Can delete local files after playback (useful for temp files)
258
+ * - **Returns assetId**: Can still control playback if needed (pause, stop, etc.)
259
+ *
260
+ * **Use Cases:**
261
+ * - Notification sounds
262
+ * - UI sound effects (button clicks, alerts)
263
+ * - Short audio clips that play once
264
+ * - Temporary audio files that should be cleaned up
265
+ *
266
+ * **Comparison with regular play():**
267
+ * - `play()`: Requires manual preload, play, and unload steps
268
+ * - `playOnce()`: Handles everything automatically with a single call
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * // Simple one-shot playback
273
+ * await NativeAudio.playOnce({ assetPath: 'audio/notification.mp3' });
274
+ *
275
+ * // Play and delete the file after completion
276
+ * await NativeAudio.playOnce({
277
+ * assetPath: 'file:///path/to/temp/audio.mp3',
278
+ * isUrl: true,
279
+ * deleteAfterPlay: true
280
+ * });
281
+ *
282
+ * // Get the assetId to control playback
283
+ * const { assetId } = await NativeAudio.playOnce({
284
+ * assetPath: 'audio/long-track.mp3',
285
+ * autoPlay: true
286
+ * });
287
+ * // Later, you can stop it manually if needed
288
+ * await NativeAudio.stop({ assetId });
289
+ * ```
290
+ *
291
+ * @since 7.11.0
292
+ * @param options {@link PlayOnceOptions}
293
+ * @returns {Promise<PlayOnceResult>} Object containing the generated assetId
294
+ */
295
+ playOnce(options: PlayOnceOptions): Promise<PlayOnceResult>;
189
296
  /**
190
297
  * Check if an audio file is preloaded
191
298
  *
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nexport interface CompletedEvent {\n /**\n * Emit when a play completes\n *\n * @since 5.0.0\n */\n assetId: string;\n}\nexport type CompletedListener = (state: CompletedEvent) => void;\nexport interface Assets {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n}\nexport interface AssetVolume {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Volume of the audio, between 0.1 and 1.0\n */\n volume: number;\n}\n\nexport interface AssetRate {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Rate of the audio, between 0.1 and 1.0\n */\n rate: number;\n}\n\nexport interface AssetPlayOptions {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Time to start playing the audio, in milliseconds\n */\n time?: number;\n /**\n * Delay to start playing the audio, in milliseconds\n */\n delay?: number;\n}\n\nexport interface ConfigureOptions {\n /**\n * Play the audio with Fade effect, only available for IOS\n */\n fade?: boolean;\n /**\n * focus the audio with Audio Focus\n */\n focus?: boolean;\n /**\n * Play the audio in the background\n */\n background?: boolean;\n /**\n * Ignore silent mode, works only on iOS setting this will nuke other audio apps\n */\n ignoreSilent?: boolean;\n /**\n * Show audio playback in the notification center (iOS and Android)\n * When enabled, displays audio metadata (title, artist, album, artwork) in the system notification\n * and Control Center (iOS) or lock screen.\n *\n * **Important iOS Behavior:**\n * Enabling this option changes the audio session category to `.playback` with `.default` mode,\n * which means your app's audio will **interrupt** other apps' audio (like background music from\n * Spotify, Apple Music, etc.) instead of mixing with it. This is required for the Now Playing\n * info to appear in Control Center and on the lock screen.\n *\n * **Trade-offs:**\n * - `showNotification: true` → Shows Now Playing controls, but interrupts other audio\n * - `showNotification: false` → Audio mixes with other apps, but no Now Playing controls\n *\n * Use this when your app is the primary audio source (music players, podcast apps, etc.).\n * Disable this for secondary audio like sound effects or notification sounds where mixing\n * with background music is preferred.\n *\n * @see https://github.com/Cap-go/capacitor-native-audio/issues/202\n */\n showNotification?: boolean;\n}\n\n/**\n * Metadata to display in the notification center, Control Center (iOS), and lock screen\n * when `showNotification` is enabled in `configure()`.\n *\n * Note: This metadata will only be displayed if `showNotification: true` is set in the\n * `configure()` method. See {@link ConfigureOptions.showNotification} for important\n * behavior details about audio mixing on iOS.\n */\nexport interface NotificationMetadata {\n /**\n * The title to display in the notification center\n */\n title?: string;\n /**\n * The artist name to display in the notification center\n */\n artist?: string;\n /**\n * The album name to display in the notification center\n */\n album?: string;\n /**\n * URL or local path to the artwork/album art image\n */\n artworkUrl?: string;\n}\n\nexport interface PreloadOptions {\n /**\n * Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)\n * Supported formats:\n * - MP3, WAV (all platforms)\n * - M3U8/HLS streams (iOS and Android)\n */\n assetPath: string;\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Volume of the audio, between 0.1 and 1.0\n */\n volume?: number;\n /**\n * Audio channel number, default is 1\n */\n audioChannelNum?: number;\n /**\n * Is the audio file a URL, pass true if assetPath is a `file://` url\n * or a streaming URL (m3u8)\n */\n isUrl?: boolean;\n /**\n * Metadata to display in the notification center when audio is playing.\n * Only used when `showNotification: true` is set in `configure()`.\n *\n * See {@link ConfigureOptions.showNotification} for important details about\n * how this affects audio mixing behavior on iOS.\n *\n * @see NotificationMetadata\n */\n notificationMetadata?: NotificationMetadata;\n /**\n * Custom HTTP headers to include when fetching remote audio files.\n * Only used when isUrl is true and assetPath is a remote URL (http/https).\n * Example: { 'x-api-key': 'abc123', 'Authorization': 'Bearer token' }\n *\n * @since 7.10.0\n */\n headers?: Record<string, string>;\n}\n\nexport interface CurrentTimeEvent {\n /**\n * Current time of the audio in seconds\n * @since 6.5.0\n */\n currentTime: number;\n /**\n * Asset Id of the audio\n * @since 6.5.0\n */\n assetId: string;\n}\nexport type CurrentTimeListener = (state: CurrentTimeEvent) => void;\n\nexport interface NativeAudio {\n /**\n * Configure the audio player\n * @since 5.0.0\n * @param option {@link ConfigureOptions}\n * @returns\n */\n configure(options: ConfigureOptions): Promise<void>;\n /**\n * Load an audio file\n * @since 5.0.0\n * @param option {@link PreloadOptions}\n * @returns\n */\n preload(options: PreloadOptions): Promise<void>;\n /**\n * Check if an audio file is preloaded\n *\n * @since 6.1.0\n * @param option {@link Assets}\n * @returns {Promise<boolean>}\n */\n isPreloaded(options: PreloadOptions): Promise<{ found: boolean }>;\n /**\n * Play an audio file\n * @since 5.0.0\n * @param option {@link PlayOptions}\n * @returns\n */\n play(options: { assetId: string; time?: number; delay?: number }): Promise<void>;\n /**\n * Pause an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n pause(options: Assets): Promise<void>;\n /**\n * Resume an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n resume(options: Assets): Promise<void>;\n /**\n * Stop an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n loop(options: Assets): Promise<void>;\n /**\n * Stop an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n stop(options: Assets): Promise<void>;\n /**\n * Unload an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n unload(options: Assets): Promise<void>;\n /**\n * Set the volume of an audio file\n * @since 5.0.0\n * @param option {@link AssetVolume}\n * @returns {Promise<void>}\n */\n setVolume(options: { assetId: string; volume: number }): Promise<void>;\n /**\n * Set the rate of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<void>}\n */\n setRate(options: { assetId: string; rate: number }): Promise<void>;\n /**\n * Set the current time of an audio file\n * @since 6.5.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<void>}\n */\n setCurrentTime(options: { assetId: string; time: number }): Promise<void>;\n /**\n * Get the current time of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<{ currentTime: number }>}\n */\n getCurrentTime(options: { assetId: string }): Promise<{ currentTime: number }>;\n /**\n * Get the duration of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<{ duration: number }>}\n */\n getDuration(options: Assets): Promise<{ duration: number }>;\n /**\n * Check if an audio file is playing\n *\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<boolean>}\n */\n isPlaying(options: Assets): Promise<{ isPlaying: boolean }>;\n /**\n * Listen for complete event\n *\n * @since 5.0.0\n * return {@link CompletedEvent}\n */\n addListener(eventName: 'complete', listenerFunc: CompletedListener): Promise<PluginListenerHandle>;\n /**\n * Listen for current time updates\n * Emits every 100ms while audio is playing\n *\n * @since 6.5.0\n * return {@link CurrentTimeEvent}\n */\n addListener(eventName: 'currentTime', listenerFunc: CurrentTimeListener): Promise<PluginListenerHandle>;\n /**\n * Clear the audio cache for remote audio files\n * @since 6.5.0\n * @returns {Promise<void>}\n */\n clearCache(): Promise<void>;\n\n /**\n * Get the native Capacitor plugin version\n *\n * @returns {Promise<{ id: string }>} an Promise with version for this device\n * @throws An error if the something went wrong\n */\n getPluginVersion(): Promise<{ version: string }>;\n\n /**\n * Deinitialize the plugin and restore original audio session settings\n * This method stops all playing audio and reverts any audio session changes made by the plugin\n * Use this when you need to ensure compatibility with other audio plugins\n *\n * @since 7.7.0\n * @returns {Promise<void>}\n */\n deinitPlugin(): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nexport interface CompletedEvent {\n /**\n * Emit when a play completes\n *\n * @since 5.0.0\n */\n assetId: string;\n}\nexport type CompletedListener = (state: CompletedEvent) => void;\nexport interface Assets {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n}\nexport interface AssetVolume {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Volume of the audio, between 0.1 and 1.0\n */\n volume: number;\n}\n\nexport interface AssetRate {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Rate of the audio, between 0.1 and 1.0\n */\n rate: number;\n}\n\nexport interface AssetPlayOptions {\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Time to start playing the audio, in milliseconds\n */\n time?: number;\n /**\n * Delay to start playing the audio, in milliseconds\n */\n delay?: number;\n}\n\nexport interface ConfigureOptions {\n /**\n * Play the audio with Fade effect, only available for IOS\n */\n fade?: boolean;\n /**\n * focus the audio with Audio Focus\n */\n focus?: boolean;\n /**\n * Play the audio in the background\n */\n background?: boolean;\n /**\n * Ignore silent mode, works only on iOS setting this will nuke other audio apps\n */\n ignoreSilent?: boolean;\n /**\n * Show audio playback in the notification center (iOS and Android)\n * When enabled, displays audio metadata (title, artist, album, artwork) in the system notification\n * and Control Center (iOS) or lock screen.\n *\n * **Important iOS Behavior:**\n * Enabling this option changes the audio session category to `.playback` with `.default` mode,\n * which means your app's audio will **interrupt** other apps' audio (like background music from\n * Spotify, Apple Music, etc.) instead of mixing with it. This is required for the Now Playing\n * info to appear in Control Center and on the lock screen.\n *\n * **Trade-offs:**\n * - `showNotification: true` → Shows Now Playing controls, but interrupts other audio\n * - `showNotification: false` → Audio mixes with other apps, but no Now Playing controls\n *\n * Use this when your app is the primary audio source (music players, podcast apps, etc.).\n * Disable this for secondary audio like sound effects or notification sounds where mixing\n * with background music is preferred.\n *\n * @see https://github.com/Cap-go/capacitor-native-audio/issues/202\n */\n showNotification?: boolean;\n}\n\n/**\n * Metadata to display in the notification center, Control Center (iOS), and lock screen\n * when `showNotification` is enabled in `configure()`.\n *\n * Note: This metadata will only be displayed if `showNotification: true` is set in the\n * `configure()` method. See {@link ConfigureOptions.showNotification} for important\n * behavior details about audio mixing on iOS.\n */\nexport interface NotificationMetadata {\n /**\n * The title to display in the notification center\n */\n title?: string;\n /**\n * The artist name to display in the notification center\n */\n artist?: string;\n /**\n * The album name to display in the notification center\n */\n album?: string;\n /**\n * URL or local path to the artwork/album art image\n */\n artworkUrl?: string;\n}\n\nexport interface PlayOnceOptions {\n /**\n * Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)\n * Supported formats:\n * - MP3, WAV (all platforms)\n * - M3U8/HLS streams (iOS and Android)\n */\n assetPath: string;\n /**\n * Volume of the audio, between 0.1 and 1.0\n * @default 1.0\n */\n volume?: number;\n /**\n * Is the audio file a URL, pass true if assetPath is a `file://` url\n * or a streaming URL (m3u8)\n * @default false\n */\n isUrl?: boolean;\n /**\n * Automatically start playback after loading\n * @default true\n */\n autoPlay?: boolean;\n /**\n * Delete the audio file from disk after playback completes\n * Only works for local files (file:// URLs), ignored for remote URLs\n * @default false\n * @since 7.11.0\n */\n deleteAfterPlay?: boolean;\n /**\n * Metadata to display in the notification center when audio is playing.\n * Only used when `showNotification: true` is set in `configure()`.\n *\n * See {@link ConfigureOptions.showNotification} for important details about\n * how this affects audio mixing behavior on iOS.\n *\n * @see NotificationMetadata\n * @since 7.10.0\n */\n notificationMetadata?: NotificationMetadata;\n /**\n * Custom HTTP headers to include when fetching remote audio files.\n * Only used when isUrl is true and assetPath is a remote URL (http/https).\n * Example: { 'x-api-key': 'abc123', 'Authorization': 'Bearer token' }\n *\n * @since 7.10.0\n */\n headers?: Record<string, string>;\n}\n\nexport interface PlayOnceResult {\n /**\n * The internally generated asset ID for this playback\n * Can be used to control playback (pause, stop, etc.) before completion\n */\n assetId: string;\n}\n\nexport interface PreloadOptions {\n /**\n * Path to the audio file, relative path of the file, absolute url (file://) or remote url (https://)\n * Supported formats:\n * - MP3, WAV (all platforms)\n * - M3U8/HLS streams (iOS and Android)\n */\n assetPath: string;\n /**\n * Asset Id, unique identifier of the file\n */\n assetId: string;\n /**\n * Volume of the audio, between 0.1 and 1.0\n */\n volume?: number;\n /**\n * Audio channel number, default is 1\n */\n audioChannelNum?: number;\n /**\n * Is the audio file a URL, pass true if assetPath is a `file://` url\n * or a streaming URL (m3u8)\n */\n isUrl?: boolean;\n /**\n * Metadata to display in the notification center when audio is playing.\n * Only used when `showNotification: true` is set in `configure()`.\n *\n * See {@link ConfigureOptions.showNotification} for important details about\n * how this affects audio mixing behavior on iOS.\n *\n * @see NotificationMetadata\n */\n notificationMetadata?: NotificationMetadata;\n /**\n * Custom HTTP headers to include when fetching remote audio files.\n * Only used when isUrl is true and assetPath is a remote URL (http/https).\n * Example: { 'x-api-key': 'abc123', 'Authorization': 'Bearer token' }\n *\n * @since 7.10.0\n */\n headers?: Record<string, string>;\n}\n\nexport interface CurrentTimeEvent {\n /**\n * Current time of the audio in seconds\n * @since 6.5.0\n */\n currentTime: number;\n /**\n * Asset Id of the audio\n * @since 6.5.0\n */\n assetId: string;\n}\nexport type CurrentTimeListener = (state: CurrentTimeEvent) => void;\n\nexport interface NativeAudio {\n /**\n * Configure the audio player\n * @since 5.0.0\n * @param option {@link ConfigureOptions}\n * @returns\n */\n configure(options: ConfigureOptions): Promise<void>;\n /**\n * Load an audio file\n * @since 5.0.0\n * @param option {@link PreloadOptions}\n * @returns\n */\n preload(options: PreloadOptions): Promise<void>;\n /**\n * Play an audio file once with automatic cleanup\n *\n * Method designed for simple, single-shot audio playback,\n * such as notification sounds, UI feedback, or other short audio clips\n * that don't require manual state management.\n *\n * **Key Features:**\n * - **Fire-and-forget**: No need to manually preload, play, stop, or unload\n * - **Auto-cleanup**: Asset is automatically unloaded after playback completes\n * - **Optional file deletion**: Can delete local files after playback (useful for temp files)\n * - **Returns assetId**: Can still control playback if needed (pause, stop, etc.)\n *\n * **Use Cases:**\n * - Notification sounds\n * - UI sound effects (button clicks, alerts)\n * - Short audio clips that play once\n * - Temporary audio files that should be cleaned up\n *\n * **Comparison with regular play():**\n * - `play()`: Requires manual preload, play, and unload steps\n * - `playOnce()`: Handles everything automatically with a single call\n *\n * @example\n * ```typescript\n * // Simple one-shot playback\n * await NativeAudio.playOnce({ assetPath: 'audio/notification.mp3' });\n *\n * // Play and delete the file after completion\n * await NativeAudio.playOnce({\n * assetPath: 'file:///path/to/temp/audio.mp3',\n * isUrl: true,\n * deleteAfterPlay: true\n * });\n *\n * // Get the assetId to control playback\n * const { assetId } = await NativeAudio.playOnce({\n * assetPath: 'audio/long-track.mp3',\n * autoPlay: true\n * });\n * // Later, you can stop it manually if needed\n * await NativeAudio.stop({ assetId });\n * ```\n *\n * @since 7.11.0\n * @param options {@link PlayOnceOptions}\n * @returns {Promise<PlayOnceResult>} Object containing the generated assetId\n */\n playOnce(options: PlayOnceOptions): Promise<PlayOnceResult>;\n /**\n * Check if an audio file is preloaded\n *\n * @since 6.1.0\n * @param option {@link Assets}\n * @returns {Promise<boolean>}\n */\n isPreloaded(options: PreloadOptions): Promise<{ found: boolean }>;\n /**\n * Play an audio file\n * @since 5.0.0\n * @param option {@link PlayOptions}\n * @returns\n */\n play(options: { assetId: string; time?: number; delay?: number }): Promise<void>;\n /**\n * Pause an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n pause(options: Assets): Promise<void>;\n /**\n * Resume an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n resume(options: Assets): Promise<void>;\n /**\n * Stop an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n loop(options: Assets): Promise<void>;\n /**\n * Stop an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n stop(options: Assets): Promise<void>;\n /**\n * Unload an audio file\n * @since 5.0.0\n * @param option {@link Assets}\n * @returns\n */\n unload(options: Assets): Promise<void>;\n /**\n * Set the volume of an audio file\n * @since 5.0.0\n * @param option {@link AssetVolume}\n * @returns {Promise<void>}\n */\n setVolume(options: { assetId: string; volume: number }): Promise<void>;\n /**\n * Set the rate of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<void>}\n */\n setRate(options: { assetId: string; rate: number }): Promise<void>;\n /**\n * Set the current time of an audio file\n * @since 6.5.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<void>}\n */\n setCurrentTime(options: { assetId: string; time: number }): Promise<void>;\n /**\n * Get the current time of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<{ currentTime: number }>}\n */\n getCurrentTime(options: { assetId: string }): Promise<{ currentTime: number }>;\n /**\n * Get the duration of an audio file\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<{ duration: number }>}\n */\n getDuration(options: Assets): Promise<{ duration: number }>;\n /**\n * Check if an audio file is playing\n *\n * @since 5.0.0\n * @param option {@link AssetPlayOptions}\n * @returns {Promise<boolean>}\n */\n isPlaying(options: Assets): Promise<{ isPlaying: boolean }>;\n /**\n * Listen for complete event\n *\n * @since 5.0.0\n * return {@link CompletedEvent}\n */\n addListener(eventName: 'complete', listenerFunc: CompletedListener): Promise<PluginListenerHandle>;\n /**\n * Listen for current time updates\n * Emits every 100ms while audio is playing\n *\n * @since 6.5.0\n * return {@link CurrentTimeEvent}\n */\n addListener(eventName: 'currentTime', listenerFunc: CurrentTimeListener): Promise<PluginListenerHandle>;\n /**\n * Clear the audio cache for remote audio files\n * @since 6.5.0\n * @returns {Promise<void>}\n */\n clearCache(): Promise<void>;\n\n /**\n * Get the native Capacitor plugin version\n *\n * @returns {Promise<{ id: string }>} an Promise with version for this device\n * @throws An error if the something went wrong\n */\n getPluginVersion(): Promise<{ version: string }>;\n\n /**\n * Deinitialize the plugin and restore original audio session settings\n * This method stops all playing audio and reverts any audio session changes made by the plugin\n * Use this when you need to ensure compatibility with other audio plugins\n *\n * @since 7.7.0\n * @returns {Promise<void>}\n */\n deinitPlugin(): Promise<void>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
- import type { ConfigureOptions, PreloadOptions } from './definitions';
2
+ import type { ConfigureOptions, PlayOnceOptions, PlayOnceResult, PreloadOptions } from './definitions';
3
3
  import { NativeAudio } from './definitions';
4
4
  export declare class NativeAudioWeb extends WebPlugin implements NativeAudio {
5
5
  private static readonly FILE_LOCATION;
6
6
  private static readonly AUDIO_ASSET_BY_ASSET_ID;
7
+ private static readonly playOnceAssets;
7
8
  constructor();
8
9
  resume(options: {
9
10
  assetId: string;
@@ -30,6 +31,7 @@ export declare class NativeAudioWeb extends WebPlugin implements NativeAudio {
30
31
  found: boolean;
31
32
  }>;
32
33
  preload(options: PreloadOptions): Promise<void>;
34
+ playOnce(options: PlayOnceOptions): Promise<PlayOnceResult>;
33
35
  private onEnded;
34
36
  play(options: {
35
37
  assetId: string;
package/dist/esm/web.js CHANGED
@@ -65,6 +65,63 @@ export class NativeAudioWeb extends WebPlugin {
65
65
  }
66
66
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));
67
67
  }
68
+ async playOnce(options) {
69
+ var _a;
70
+ // Generate a unique temporary asset ID
71
+ const assetId = `playOnce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
72
+ NativeAudioWeb.playOnceAssets.add(assetId);
73
+ const autoPlay = options.autoPlay !== false; // Default to true
74
+ const deleteAfterPlay = (_a = options.deleteAfterPlay) !== null && _a !== void 0 ? _a : false;
75
+ try {
76
+ // Preload the asset
77
+ await this.preload({
78
+ assetId,
79
+ assetPath: options.assetPath,
80
+ volume: options.volume,
81
+ isUrl: options.isUrl,
82
+ });
83
+ // Set up automatic cleanup on completion
84
+ const audio = this.getAudioAsset(assetId).audio;
85
+ const cleanupHandler = async () => {
86
+ try {
87
+ // Unload the asset
88
+ await this.unload({ assetId });
89
+ 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
+ if (deleteAfterPlay) {
93
+ console.warn('[NativeAudio] deleteAfterPlay is not supported on web platform. File deletion is ignored.');
94
+ }
95
+ }
96
+ catch (error) {
97
+ console.error('[NativeAudio] Error during playOnce cleanup:', error);
98
+ }
99
+ };
100
+ audio.addEventListener('ended', cleanupHandler, { once: true });
101
+ // Handle errors during playback - cleanup if play fails
102
+ audio.addEventListener('error', () => {
103
+ cleanupHandler().catch((error) => {
104
+ console.error('[NativeAudio] Error during error cleanup:', error);
105
+ });
106
+ }, { once: true });
107
+ // Auto-play if requested
108
+ if (autoPlay) {
109
+ await this.play({ assetId });
110
+ }
111
+ return { assetId };
112
+ }
113
+ catch (error) {
114
+ // Cleanup on failure
115
+ try {
116
+ await this.unload({ assetId });
117
+ NativeAudioWeb.playOnceAssets.delete(assetId);
118
+ }
119
+ catch (_b) {
120
+ // Ignore cleanup errors
121
+ }
122
+ throw error;
123
+ }
124
+ }
68
125
  onEnded(assetId) {
69
126
  this.notifyListeners('complete', { assetId });
70
127
  }
@@ -145,6 +202,7 @@ export class NativeAudioWeb extends WebPlugin {
145
202
  }
146
203
  NativeAudioWeb.FILE_LOCATION = '';
147
204
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID = new Map();
205
+ NativeAudioWeb.playOnceAssets = new Set();
148
206
  const NativeAudio = new NativeAudioWeb();
149
207
  export { NativeAudio };
150
208
  //# sourceMappingURL=web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport { AudioAsset } from './audio-asset';\nimport type { ConfigureOptions, PreloadOptions } from './definitions';\nimport { NativeAudio } from './definitions';\n\nexport class NativeAudioWeb extends WebPlugin implements NativeAudio {\n private static readonly FILE_LOCATION: string = '';\n private static readonly AUDIO_ASSET_BY_ASSET_ID: Map<string, AudioAsset> = new Map<string, AudioAsset>();\n\n constructor() {\n super();\n }\n\n async resume(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n if (audio.paused) {\n return audio.play();\n }\n }\n\n async pause(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return audio.pause();\n }\n\n async setCurrentTime(options: { assetId: string; time: number }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.currentTime = options.time;\n return;\n }\n\n async getCurrentTime(options: { assetId: string }): Promise<{ currentTime: number }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return { currentTime: audio.currentTime };\n }\n\n async getDuration(options: { assetId: string }): Promise<{ duration: number }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n if (Number.isNaN(audio.duration)) {\n throw 'no duration available';\n }\n if (!Number.isFinite(audio.duration)) {\n throw 'duration not available => media resource is streaming';\n }\n return { duration: audio.duration };\n }\n\n async configure(options: ConfigureOptions): Promise<void> {\n throw `configure is not supported for web: ${JSON.stringify(options)}`;\n }\n\n async isPreloaded(options: PreloadOptions): Promise<{ found: boolean }> {\n try {\n return { found: !!this.getAudioAsset(options.assetId) };\n } catch (e) {\n return { found: false };\n }\n }\n\n async preload(options: PreloadOptions): Promise<void> {\n if (NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(options.assetId)) {\n throw 'AssetId already exists. Unload first if like to change!';\n }\n if (!options.assetPath?.length) {\n throw 'no assetPath provided';\n }\n if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {\n const slashPrefix: string = options.assetPath.startsWith('/') ? '' : '/';\n options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;\n }\n const audio: HTMLAudioElement = new Audio(options.assetPath);\n audio.autoplay = false;\n audio.loop = false;\n audio.preload = 'auto';\n if (options.volume) {\n audio.volume = options.volume;\n }\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));\n }\n private onEnded(assetId: string): void {\n this.notifyListeners('complete', { assetId });\n }\n\n async play(options: { assetId: string; time?: number }): Promise<void> {\n const { assetId, time = 0 } = options;\n const audio = this.getAudioAsset(assetId).audio;\n await this.stop(options);\n audio.loop = false;\n audio.currentTime = time;\n audio.addEventListener('ended', () => this.onEnded(assetId), {\n once: true,\n });\n return audio.play();\n }\n\n async loop(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n await this.stop(options);\n audio.loop = true;\n return audio.play();\n }\n\n async stop(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.pause();\n audio.loop = false;\n audio.currentTime = 0;\n }\n\n async unload(options: { assetId: string }): Promise<void> {\n await this.stop(options);\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.delete(options.assetId);\n }\n\n async setVolume(options: { assetId: string; volume: number }): Promise<void> {\n if (typeof options?.volume !== 'number') {\n throw 'no volume provided';\n }\n\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.volume = options.volume;\n }\n\n async setRate(options: { assetId: string; rate: number }): Promise<void> {\n if (typeof options?.rate !== 'number') {\n throw 'no rate provided';\n }\n\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.playbackRate = options.rate;\n }\n\n async isPlaying(options: { assetId: string }): Promise<{ isPlaying: boolean }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return { isPlaying: !audio.paused };\n }\n\n async clearCache(): Promise<void> {\n // Web audio doesn't have a persistent cache to clear\n return;\n }\n\n private getAudioAsset(assetId: string): AudioAsset {\n this.checkAssetId(assetId);\n\n if (!NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(assetId)) {\n throw `no asset for assetId \"${assetId}\" available. Call preload first!`;\n }\n\n return NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.get(assetId) as AudioAsset;\n }\n\n private checkAssetId(assetId: string): void {\n if (typeof assetId !== 'string') {\n throw 'assetId must be a string';\n }\n\n if (!assetId?.length) {\n throw 'no assetId provided';\n }\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n\n async deinitPlugin(): Promise<void> {\n // Stop and unload all audio assets\n for (const [assetId] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID) {\n await this.unload({ assetId });\n }\n return;\n }\n}\n\nconst NativeAudio = new NativeAudioWeb();\n\nexport { NativeAudio };\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport { AudioAsset } from './audio-asset';\nimport type { ConfigureOptions, PlayOnceOptions, PlayOnceResult, PreloadOptions } from './definitions';\nimport { NativeAudio } from './definitions';\n\nexport class NativeAudioWeb extends WebPlugin implements NativeAudio {\n private static readonly FILE_LOCATION: string = '';\n private static readonly AUDIO_ASSET_BY_ASSET_ID: Map<string, AudioAsset> = new Map<string, AudioAsset>();\n private static readonly playOnceAssets: Set<string> = new Set<string>();\n constructor() {\n super();\n }\n\n async resume(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n if (audio.paused) {\n return audio.play();\n }\n }\n\n async pause(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return audio.pause();\n }\n\n async setCurrentTime(options: { assetId: string; time: number }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.currentTime = options.time;\n return;\n }\n\n async getCurrentTime(options: { assetId: string }): Promise<{ currentTime: number }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return { currentTime: audio.currentTime };\n }\n\n async getDuration(options: { assetId: string }): Promise<{ duration: number }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n if (Number.isNaN(audio.duration)) {\n throw 'no duration available';\n }\n if (!Number.isFinite(audio.duration)) {\n throw 'duration not available => media resource is streaming';\n }\n return { duration: audio.duration };\n }\n\n async configure(options: ConfigureOptions): Promise<void> {\n throw `configure is not supported for web: ${JSON.stringify(options)}`;\n }\n\n async isPreloaded(options: PreloadOptions): Promise<{ found: boolean }> {\n try {\n return { found: !!this.getAudioAsset(options.assetId) };\n } catch (e) {\n return { found: false };\n }\n }\n\n async preload(options: PreloadOptions): Promise<void> {\n if (NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(options.assetId)) {\n throw 'AssetId already exists. Unload first if like to change!';\n }\n if (!options.assetPath?.length) {\n throw 'no assetPath provided';\n }\n if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {\n const slashPrefix: string = options.assetPath.startsWith('/') ? '' : '/';\n options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;\n }\n const audio: HTMLAudioElement = new Audio(options.assetPath);\n audio.autoplay = false;\n audio.loop = false;\n audio.preload = 'auto';\n if (options.volume) {\n audio.volume = options.volume;\n }\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));\n }\n\n async playOnce(options: PlayOnceOptions): Promise<PlayOnceResult> {\n // Generate a unique temporary asset ID\n const assetId = `playOnce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n NativeAudioWeb.playOnceAssets.add(assetId);\n\n const autoPlay = options.autoPlay !== false; // Default to true\n const deleteAfterPlay = options.deleteAfterPlay ?? false;\n\n try {\n // Preload the asset\n await this.preload({\n assetId,\n assetPath: options.assetPath,\n volume: options.volume,\n isUrl: options.isUrl,\n });\n\n // Set up automatic cleanup on completion\n const audio = this.getAudioAsset(assetId).audio;\n const cleanupHandler = async () => {\n try {\n // Unload the asset\n await this.unload({ assetId });\n NativeAudioWeb.playOnceAssets.delete(assetId);\n\n // Delete file if requested (Web can't actually delete files from disk)\n // This is a no-op on web, but we keep the interface consistent\n if (deleteAfterPlay) {\n console.warn('[NativeAudio] deleteAfterPlay is not supported on web platform. File deletion is ignored.');\n }\n } catch (error) {\n console.error('[NativeAudio] Error during playOnce cleanup:', error);\n }\n };\n\n audio.addEventListener('ended', cleanupHandler, { once: true });\n\n // Handle errors during playback - cleanup if play fails\n audio.addEventListener(\n 'error',\n () => {\n cleanupHandler().catch((error) => {\n console.error('[NativeAudio] Error during error cleanup:', error);\n });\n },\n { once: true },\n );\n\n // Auto-play if requested\n if (autoPlay) {\n await this.play({ assetId });\n }\n\n return { assetId };\n } catch (error) {\n // Cleanup on failure\n try {\n await this.unload({ assetId });\n NativeAudioWeb.playOnceAssets.delete(assetId);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n }\n\n private onEnded(assetId: string): void {\n this.notifyListeners('complete', { assetId });\n }\n\n async play(options: { assetId: string; time?: number }): Promise<void> {\n const { assetId, time = 0 } = options;\n const audio = this.getAudioAsset(assetId).audio;\n await this.stop(options);\n audio.loop = false;\n audio.currentTime = time;\n audio.addEventListener('ended', () => this.onEnded(assetId), {\n once: true,\n });\n return audio.play();\n }\n\n async loop(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n await this.stop(options);\n audio.loop = true;\n return audio.play();\n }\n\n async stop(options: { assetId: string }): Promise<void> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.pause();\n audio.loop = false;\n audio.currentTime = 0;\n }\n\n async unload(options: { assetId: string }): Promise<void> {\n await this.stop(options);\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.delete(options.assetId);\n }\n\n async setVolume(options: { assetId: string; volume: number }): Promise<void> {\n if (typeof options?.volume !== 'number') {\n throw 'no volume provided';\n }\n\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.volume = options.volume;\n }\n\n async setRate(options: { assetId: string; rate: number }): Promise<void> {\n if (typeof options?.rate !== 'number') {\n throw 'no rate provided';\n }\n\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n audio.playbackRate = options.rate;\n }\n\n async isPlaying(options: { assetId: string }): Promise<{ isPlaying: boolean }> {\n const audio: HTMLAudioElement = this.getAudioAsset(options.assetId).audio;\n return { isPlaying: !audio.paused };\n }\n\n async clearCache(): Promise<void> {\n // Web audio doesn't have a persistent cache to clear\n return;\n }\n\n private getAudioAsset(assetId: string): AudioAsset {\n this.checkAssetId(assetId);\n\n if (!NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(assetId)) {\n throw `no asset for assetId \"${assetId}\" available. Call preload first!`;\n }\n\n return NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.get(assetId) as AudioAsset;\n }\n\n private checkAssetId(assetId: string): void {\n if (typeof assetId !== 'string') {\n throw 'assetId must be a string';\n }\n\n if (!assetId?.length) {\n throw 'no assetId provided';\n }\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n\n async deinitPlugin(): Promise<void> {\n // Stop and unload all audio assets\n for (const [assetId] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID) {\n await this.unload({ assetId });\n }\n return;\n }\n}\n\nconst NativeAudio = new NativeAudioWeb();\n\nexport { NativeAudio };\n"]}
@@ -77,6 +77,63 @@ class NativeAudioWeb extends core.WebPlugin {
77
77
  }
78
78
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));
79
79
  }
80
+ async playOnce(options) {
81
+ var _a;
82
+ // Generate a unique temporary asset ID
83
+ const assetId = `playOnce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
84
+ NativeAudioWeb.playOnceAssets.add(assetId);
85
+ const autoPlay = options.autoPlay !== false; // Default to true
86
+ const deleteAfterPlay = (_a = options.deleteAfterPlay) !== null && _a !== void 0 ? _a : false;
87
+ try {
88
+ // Preload the asset
89
+ await this.preload({
90
+ assetId,
91
+ assetPath: options.assetPath,
92
+ volume: options.volume,
93
+ isUrl: options.isUrl,
94
+ });
95
+ // Set up automatic cleanup on completion
96
+ const audio = this.getAudioAsset(assetId).audio;
97
+ const cleanupHandler = async () => {
98
+ try {
99
+ // Unload the asset
100
+ await this.unload({ assetId });
101
+ 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
+ if (deleteAfterPlay) {
105
+ console.warn('[NativeAudio] deleteAfterPlay is not supported on web platform. File deletion is ignored.');
106
+ }
107
+ }
108
+ catch (error) {
109
+ console.error('[NativeAudio] Error during playOnce cleanup:', error);
110
+ }
111
+ };
112
+ audio.addEventListener('ended', cleanupHandler, { once: true });
113
+ // Handle errors during playback - cleanup if play fails
114
+ audio.addEventListener('error', () => {
115
+ cleanupHandler().catch((error) => {
116
+ console.error('[NativeAudio] Error during error cleanup:', error);
117
+ });
118
+ }, { once: true });
119
+ // Auto-play if requested
120
+ if (autoPlay) {
121
+ await this.play({ assetId });
122
+ }
123
+ return { assetId };
124
+ }
125
+ catch (error) {
126
+ // Cleanup on failure
127
+ try {
128
+ await this.unload({ assetId });
129
+ NativeAudioWeb.playOnceAssets.delete(assetId);
130
+ }
131
+ catch (_b) {
132
+ // Ignore cleanup errors
133
+ }
134
+ throw error;
135
+ }
136
+ }
80
137
  onEnded(assetId) {
81
138
  this.notifyListeners('complete', { assetId });
82
139
  }
@@ -157,6 +214,7 @@ class NativeAudioWeb extends core.WebPlugin {
157
214
  }
158
215
  NativeAudioWeb.FILE_LOCATION = '';
159
216
  NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID = new Map();
217
+ NativeAudioWeb.playOnceAssets = new Set();
160
218
  new NativeAudioWeb();
161
219
 
162
220
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/audio-asset.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst NativeAudio = registerPlugin('NativeAudio', {\n web: () => import('./web').then((m) => new m.NativeAudioWeb()),\n});\nexport * from './definitions';\nexport { NativeAudio };\n//# sourceMappingURL=index.js.map","export class AudioAsset {\n constructor(audio) {\n this.audio = audio;\n }\n}\n//# sourceMappingURL=audio-asset.js.map","import { WebPlugin } from '@capacitor/core';\nimport { AudioAsset } from './audio-asset';\nexport class NativeAudioWeb extends WebPlugin {\n constructor() {\n super();\n }\n async resume(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n if (audio.paused) {\n return audio.play();\n }\n }\n async pause(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return audio.pause();\n }\n async setCurrentTime(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.currentTime = options.time;\n return;\n }\n async getCurrentTime(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return { currentTime: audio.currentTime };\n }\n async getDuration(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n if (Number.isNaN(audio.duration)) {\n throw 'no duration available';\n }\n if (!Number.isFinite(audio.duration)) {\n throw 'duration not available => media resource is streaming';\n }\n return { duration: audio.duration };\n }\n async configure(options) {\n throw `configure is not supported for web: ${JSON.stringify(options)}`;\n }\n async isPreloaded(options) {\n try {\n return { found: !!this.getAudioAsset(options.assetId) };\n }\n catch (e) {\n return { found: false };\n }\n }\n async preload(options) {\n var _a;\n if (NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(options.assetId)) {\n throw 'AssetId already exists. Unload first if like to change!';\n }\n if (!((_a = options.assetPath) === null || _a === void 0 ? void 0 : _a.length)) {\n throw 'no assetPath provided';\n }\n if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {\n const slashPrefix = options.assetPath.startsWith('/') ? '' : '/';\n options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;\n }\n const audio = new Audio(options.assetPath);\n audio.autoplay = false;\n audio.loop = false;\n audio.preload = 'auto';\n if (options.volume) {\n audio.volume = options.volume;\n }\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));\n }\n onEnded(assetId) {\n this.notifyListeners('complete', { assetId });\n }\n async play(options) {\n const { assetId, time = 0 } = options;\n const audio = this.getAudioAsset(assetId).audio;\n await this.stop(options);\n audio.loop = false;\n audio.currentTime = time;\n audio.addEventListener('ended', () => this.onEnded(assetId), {\n once: true,\n });\n return audio.play();\n }\n async loop(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n await this.stop(options);\n audio.loop = true;\n return audio.play();\n }\n async stop(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.pause();\n audio.loop = false;\n audio.currentTime = 0;\n }\n async unload(options) {\n await this.stop(options);\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.delete(options.assetId);\n }\n async setVolume(options) {\n if (typeof (options === null || options === void 0 ? void 0 : options.volume) !== 'number') {\n throw 'no volume provided';\n }\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.volume = options.volume;\n }\n async setRate(options) {\n if (typeof (options === null || options === void 0 ? void 0 : options.rate) !== 'number') {\n throw 'no rate provided';\n }\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.playbackRate = options.rate;\n }\n async isPlaying(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return { isPlaying: !audio.paused };\n }\n async clearCache() {\n // Web audio doesn't have a persistent cache to clear\n return;\n }\n getAudioAsset(assetId) {\n this.checkAssetId(assetId);\n if (!NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(assetId)) {\n throw `no asset for assetId \"${assetId}\" available. Call preload first!`;\n }\n return NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.get(assetId);\n }\n checkAssetId(assetId) {\n if (typeof assetId !== 'string') {\n throw 'assetId must be a string';\n }\n if (!(assetId === null || assetId === void 0 ? void 0 : assetId.length)) {\n throw 'no assetId provided';\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n async deinitPlugin() {\n // Stop and unload all audio assets\n for (const [assetId] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID) {\n await this.unload({ assetId });\n }\n return;\n }\n}\nNativeAudioWeb.FILE_LOCATION = '';\nNativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID = new Map();\nconst NativeAudio = new NativeAudioWeb();\nexport { NativeAudio };\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/audio-asset.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst NativeAudio = registerPlugin('NativeAudio', {\n web: () => import('./web').then((m) => new m.NativeAudioWeb()),\n});\nexport * from './definitions';\nexport { NativeAudio };\n//# sourceMappingURL=index.js.map","export class AudioAsset {\n constructor(audio) {\n this.audio = audio;\n }\n}\n//# sourceMappingURL=audio-asset.js.map","import { WebPlugin } from '@capacitor/core';\nimport { AudioAsset } from './audio-asset';\nexport class NativeAudioWeb extends WebPlugin {\n constructor() {\n super();\n }\n async resume(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n if (audio.paused) {\n return audio.play();\n }\n }\n async pause(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return audio.pause();\n }\n async setCurrentTime(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.currentTime = options.time;\n return;\n }\n async getCurrentTime(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return { currentTime: audio.currentTime };\n }\n async getDuration(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n if (Number.isNaN(audio.duration)) {\n throw 'no duration available';\n }\n if (!Number.isFinite(audio.duration)) {\n throw 'duration not available => media resource is streaming';\n }\n return { duration: audio.duration };\n }\n async configure(options) {\n throw `configure is not supported for web: ${JSON.stringify(options)}`;\n }\n async isPreloaded(options) {\n try {\n return { found: !!this.getAudioAsset(options.assetId) };\n }\n catch (e) {\n return { found: false };\n }\n }\n async preload(options) {\n var _a;\n if (NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(options.assetId)) {\n throw 'AssetId already exists. Unload first if like to change!';\n }\n if (!((_a = options.assetPath) === null || _a === void 0 ? void 0 : _a.length)) {\n throw 'no assetPath provided';\n }\n if (!options.isUrl && !new RegExp('^/?' + NativeAudioWeb.FILE_LOCATION).test(options.assetPath)) {\n const slashPrefix = options.assetPath.startsWith('/') ? '' : '/';\n options.assetPath = `${NativeAudioWeb.FILE_LOCATION}${slashPrefix}${options.assetPath}`;\n }\n const audio = new Audio(options.assetPath);\n audio.autoplay = false;\n audio.loop = false;\n audio.preload = 'auto';\n if (options.volume) {\n audio.volume = options.volume;\n }\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.set(options.assetId, new AudioAsset(audio));\n }\n async playOnce(options) {\n var _a;\n // Generate a unique temporary asset ID\n const assetId = `playOnce_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n NativeAudioWeb.playOnceAssets.add(assetId);\n const autoPlay = options.autoPlay !== false; // Default to true\n const deleteAfterPlay = (_a = options.deleteAfterPlay) !== null && _a !== void 0 ? _a : false;\n try {\n // Preload the asset\n await this.preload({\n assetId,\n assetPath: options.assetPath,\n volume: options.volume,\n isUrl: options.isUrl,\n });\n // Set up automatic cleanup on completion\n const audio = this.getAudioAsset(assetId).audio;\n const cleanupHandler = async () => {\n try {\n // Unload the asset\n await this.unload({ assetId });\n NativeAudioWeb.playOnceAssets.delete(assetId);\n // Delete file if requested (Web can't actually delete files from disk)\n // This is a no-op on web, but we keep the interface consistent\n if (deleteAfterPlay) {\n console.warn('[NativeAudio] deleteAfterPlay is not supported on web platform. File deletion is ignored.');\n }\n }\n catch (error) {\n console.error('[NativeAudio] Error during playOnce cleanup:', error);\n }\n };\n audio.addEventListener('ended', cleanupHandler, { once: true });\n // Handle errors during playback - cleanup if play fails\n audio.addEventListener('error', () => {\n cleanupHandler().catch((error) => {\n console.error('[NativeAudio] Error during error cleanup:', error);\n });\n }, { once: true });\n // Auto-play if requested\n if (autoPlay) {\n await this.play({ assetId });\n }\n return { assetId };\n }\n catch (error) {\n // Cleanup on failure\n try {\n await this.unload({ assetId });\n NativeAudioWeb.playOnceAssets.delete(assetId);\n }\n catch (_b) {\n // Ignore cleanup errors\n }\n throw error;\n }\n }\n onEnded(assetId) {\n this.notifyListeners('complete', { assetId });\n }\n async play(options) {\n const { assetId, time = 0 } = options;\n const audio = this.getAudioAsset(assetId).audio;\n await this.stop(options);\n audio.loop = false;\n audio.currentTime = time;\n audio.addEventListener('ended', () => this.onEnded(assetId), {\n once: true,\n });\n return audio.play();\n }\n async loop(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n await this.stop(options);\n audio.loop = true;\n return audio.play();\n }\n async stop(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.pause();\n audio.loop = false;\n audio.currentTime = 0;\n }\n async unload(options) {\n await this.stop(options);\n NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.delete(options.assetId);\n }\n async setVolume(options) {\n if (typeof (options === null || options === void 0 ? void 0 : options.volume) !== 'number') {\n throw 'no volume provided';\n }\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.volume = options.volume;\n }\n async setRate(options) {\n if (typeof (options === null || options === void 0 ? void 0 : options.rate) !== 'number') {\n throw 'no rate provided';\n }\n const audio = this.getAudioAsset(options.assetId).audio;\n audio.playbackRate = options.rate;\n }\n async isPlaying(options) {\n const audio = this.getAudioAsset(options.assetId).audio;\n return { isPlaying: !audio.paused };\n }\n async clearCache() {\n // Web audio doesn't have a persistent cache to clear\n return;\n }\n getAudioAsset(assetId) {\n this.checkAssetId(assetId);\n if (!NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.has(assetId)) {\n throw `no asset for assetId \"${assetId}\" available. Call preload first!`;\n }\n return NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID.get(assetId);\n }\n checkAssetId(assetId) {\n if (typeof assetId !== 'string') {\n throw 'assetId must be a string';\n }\n if (!(assetId === null || assetId === void 0 ? void 0 : assetId.length)) {\n throw 'no assetId provided';\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n async deinitPlugin() {\n // Stop and unload all audio assets\n for (const [assetId] of NativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID) {\n await this.unload({ assetId });\n }\n return;\n }\n}\nNativeAudioWeb.FILE_LOCATION = '';\nNativeAudioWeb.AUDIO_ASSET_BY_ASSET_ID = new Map();\nNativeAudioWeb.playOnceAssets = new Set();\nconst NativeAudio = new NativeAudioWeb();\nexport { NativeAudio };\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}