taglib-wasm 0.3.1 → 0.3.3
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/README.md +190 -97
- package/build/taglib.js +2401 -8
- package/index.ts +96 -4
- package/package.json +4 -1
- package/src/constants.ts +227 -0
- package/src/mod.ts +6 -6
- package/src/simple.ts +105 -70
- package/src/taglib.ts +246 -70
- package/src/types.ts +166 -17
- package/src/wasm-workers.ts +8 -8
- package/src/wasm.ts +21 -12
- package/src/workers.ts +111 -31
package/src/taglib.ts
CHANGED
|
@@ -1,40 +1,185 @@
|
|
|
1
1
|
import type { TagLibModule, WasmModule } from "./wasm.ts";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
AudioProperties,
|
|
4
|
+
FileType,
|
|
5
|
+
PropertyMap,
|
|
6
|
+
Tag as BasicTag,
|
|
7
|
+
} from "./types.ts";
|
|
3
8
|
|
|
4
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Extended Tag interface with read/write capabilities for audio metadata.
|
|
11
|
+
* Extends the basic Tag interface with setter methods for modifying metadata.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const file = await taglib.openFile(buffer);
|
|
16
|
+
* const tag = file.tag();
|
|
17
|
+
*
|
|
18
|
+
* // Read metadata
|
|
19
|
+
* console.log(tag.title);
|
|
20
|
+
*
|
|
21
|
+
* // Write metadata
|
|
22
|
+
* tag.setTitle("New Title");
|
|
23
|
+
* tag.setArtist("New Artist");
|
|
24
|
+
* file.save();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
5
27
|
export interface Tag extends BasicTag {
|
|
28
|
+
/** Set the track title */
|
|
6
29
|
setTitle(value: string): void;
|
|
30
|
+
/** Set the artist name */
|
|
7
31
|
setArtist(value: string): void;
|
|
32
|
+
/** Set the album name */
|
|
8
33
|
setAlbum(value: string): void;
|
|
34
|
+
/** Set the comment */
|
|
9
35
|
setComment(value: string): void;
|
|
36
|
+
/** Set the genre */
|
|
10
37
|
setGenre(value: string): void;
|
|
38
|
+
/** Set the release year */
|
|
11
39
|
setYear(value: number): void;
|
|
40
|
+
/** Set the track number */
|
|
12
41
|
setTrack(value: number): void;
|
|
13
42
|
}
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Represents an audio file with metadata and audio properties.
|
|
46
|
+
* Provides methods for reading and writing metadata, accessing audio properties,
|
|
47
|
+
* and managing format-specific features.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const file = await taglib.openFile(audioBuffer);
|
|
52
|
+
*
|
|
53
|
+
* // Check if valid
|
|
54
|
+
* if (!file.isValid()) {
|
|
55
|
+
* throw new Error("Invalid audio file");
|
|
56
|
+
* }
|
|
57
|
+
*
|
|
58
|
+
* // Read metadata
|
|
59
|
+
* const tag = file.tag();
|
|
60
|
+
* const props = file.audioProperties();
|
|
61
|
+
*
|
|
62
|
+
* // Modify and save
|
|
63
|
+
* tag.setTitle("New Title");
|
|
64
|
+
* file.save();
|
|
65
|
+
*
|
|
66
|
+
* // Get modified buffer
|
|
67
|
+
* const modifiedBuffer = file.getFileBuffer();
|
|
68
|
+
*
|
|
69
|
+
* // Clean up
|
|
70
|
+
* file.dispose();
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
18
73
|
export interface AudioFile {
|
|
74
|
+
/**
|
|
75
|
+
* Get the audio file format.
|
|
76
|
+
* @returns The detected file type (e.g., "MP3", "FLAC", "MP4")
|
|
77
|
+
*/
|
|
19
78
|
getFormat(): FileType;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the tag object for reading/writing basic metadata.
|
|
82
|
+
* @returns Tag object with getters and setters for metadata fields
|
|
83
|
+
* @throws {Error} If unable to get tag from file
|
|
84
|
+
*/
|
|
20
85
|
tag(): Tag;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get audio properties (duration, bitrate, sample rate, etc.).
|
|
89
|
+
* @returns Audio properties or null if unavailable
|
|
90
|
+
*/
|
|
21
91
|
audioProperties(): AudioProperties | null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get all metadata properties as a key-value map.
|
|
95
|
+
* Includes both standard and format-specific properties.
|
|
96
|
+
* @returns PropertyMap with all available metadata
|
|
97
|
+
*/
|
|
22
98
|
properties(): PropertyMap;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set multiple properties at once from a PropertyMap.
|
|
102
|
+
* @param properties - Map of property names to values
|
|
103
|
+
*/
|
|
23
104
|
setProperties(properties: PropertyMap): void;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get a single property value by key.
|
|
108
|
+
* @param key - Property name (e.g., "ALBUMARTIST", "ACOUSTID_ID")
|
|
109
|
+
* @returns Property value or undefined if not found
|
|
110
|
+
*/
|
|
24
111
|
getProperty(key: string): string | undefined;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Set a single property value.
|
|
115
|
+
* @param key - Property name
|
|
116
|
+
* @param value - Property value
|
|
117
|
+
*/
|
|
25
118
|
setProperty(key: string, value: string): void;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if this is an MP4/M4A file.
|
|
122
|
+
* @returns true if the file is MP4/M4A format
|
|
123
|
+
*/
|
|
26
124
|
isMP4(): boolean;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get an MP4-specific metadata item.
|
|
128
|
+
* @param key - MP4 atom name (e.g., "----:com.apple.iTunes:iTunNORM")
|
|
129
|
+
* @returns Item value or undefined if not found
|
|
130
|
+
* @throws {Error} If not an MP4 file
|
|
131
|
+
*/
|
|
27
132
|
getMP4Item(key: string): string | undefined;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Set an MP4-specific metadata item.
|
|
136
|
+
* @param key - MP4 atom name
|
|
137
|
+
* @param value - Item value
|
|
138
|
+
* @throws {Error} If not an MP4 file
|
|
139
|
+
*/
|
|
28
140
|
setMP4Item(key: string, value: string): void;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Remove an MP4-specific metadata item.
|
|
144
|
+
* @param key - MP4 atom name to remove
|
|
145
|
+
* @throws {Error} If not an MP4 file
|
|
146
|
+
*/
|
|
29
147
|
removeMP4Item(key: string): void;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Save all changes to the in-memory buffer.
|
|
151
|
+
* Note: This does not write to disk, but updates the internal buffer.
|
|
152
|
+
* Use getFileBuffer() to retrieve the modified data.
|
|
153
|
+
* @returns true if save was successful
|
|
154
|
+
*/
|
|
30
155
|
save(): boolean;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the current file data as a buffer, including any modifications.
|
|
159
|
+
* Call this after save() to get the updated file data.
|
|
160
|
+
* @returns Uint8Array containing the complete file data
|
|
161
|
+
*/
|
|
31
162
|
getFileBuffer(): Uint8Array;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Check if the file was loaded successfully and is valid.
|
|
166
|
+
* @returns true if the file is valid and can be processed
|
|
167
|
+
*/
|
|
32
168
|
isValid(): boolean;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Release all resources associated with this file.
|
|
172
|
+
* Always call this when done to prevent memory leaks.
|
|
173
|
+
*/
|
|
33
174
|
dispose(): void;
|
|
34
175
|
}
|
|
35
176
|
|
|
36
177
|
/**
|
|
37
|
-
*
|
|
178
|
+
* Implementation of AudioFile interface using Embind API.
|
|
179
|
+
* Wraps the native TagLib C++ FileHandle object.
|
|
180
|
+
*
|
|
181
|
+
* @internal This class is not meant to be instantiated directly.
|
|
182
|
+
* Use TagLib.openFile() to create instances.
|
|
38
183
|
*/
|
|
39
184
|
export class AudioFileImpl implements AudioFile {
|
|
40
185
|
private fileHandle: any;
|
|
@@ -48,22 +193,18 @@ export class AudioFileImpl implements AudioFile {
|
|
|
48
193
|
this.fileHandle = fileHandle;
|
|
49
194
|
}
|
|
50
195
|
|
|
51
|
-
/**
|
|
52
|
-
* Get file format
|
|
53
|
-
*/
|
|
196
|
+
/** @inheritdoc */
|
|
54
197
|
getFormat(): FileType {
|
|
55
198
|
return this.fileHandle.getFormat() as FileType;
|
|
56
199
|
}
|
|
57
200
|
|
|
58
|
-
/**
|
|
59
|
-
* Get tag object for reading/writing metadata
|
|
60
|
-
*/
|
|
201
|
+
/** @inheritdoc */
|
|
61
202
|
tag(): Tag {
|
|
62
203
|
const tagWrapper = this.fileHandle.getTag();
|
|
63
204
|
if (!tagWrapper) {
|
|
64
205
|
throw new Error("Failed to get tag from file");
|
|
65
206
|
}
|
|
66
|
-
|
|
207
|
+
|
|
67
208
|
return {
|
|
68
209
|
title: tagWrapper.title(),
|
|
69
210
|
artist: tagWrapper.artist(),
|
|
@@ -72,7 +213,7 @@ export class AudioFileImpl implements AudioFile {
|
|
|
72
213
|
genre: tagWrapper.genre(),
|
|
73
214
|
year: tagWrapper.year(),
|
|
74
215
|
track: tagWrapper.track(),
|
|
75
|
-
|
|
216
|
+
|
|
76
217
|
setTitle: (value: string) => tagWrapper.setTitle(value),
|
|
77
218
|
setArtist: (value: string) => tagWrapper.setArtist(value),
|
|
78
219
|
setAlbum: (value: string) => tagWrapper.setAlbum(value),
|
|
@@ -83,16 +224,14 @@ export class AudioFileImpl implements AudioFile {
|
|
|
83
224
|
};
|
|
84
225
|
}
|
|
85
226
|
|
|
86
|
-
/**
|
|
87
|
-
* Get audio properties
|
|
88
|
-
*/
|
|
227
|
+
/** @inheritdoc */
|
|
89
228
|
audioProperties(): AudioProperties | null {
|
|
90
229
|
if (!this.cachedAudioProperties) {
|
|
91
230
|
const propsWrapper = this.fileHandle.getAudioProperties();
|
|
92
231
|
if (!propsWrapper) {
|
|
93
232
|
return null;
|
|
94
233
|
}
|
|
95
|
-
|
|
234
|
+
|
|
96
235
|
this.cachedAudioProperties = {
|
|
97
236
|
length: propsWrapper.lengthInSeconds(),
|
|
98
237
|
bitrate: propsWrapper.bitrate(),
|
|
@@ -100,58 +239,46 @@ export class AudioFileImpl implements AudioFile {
|
|
|
100
239
|
channels: propsWrapper.channels(),
|
|
101
240
|
};
|
|
102
241
|
}
|
|
103
|
-
|
|
242
|
+
|
|
104
243
|
return this.cachedAudioProperties;
|
|
105
244
|
}
|
|
106
245
|
|
|
107
|
-
/**
|
|
108
|
-
* Get all properties as a PropertyMap
|
|
109
|
-
*/
|
|
246
|
+
/** @inheritdoc */
|
|
110
247
|
properties(): PropertyMap {
|
|
111
248
|
const jsObj = this.fileHandle.getProperties();
|
|
112
249
|
const result: PropertyMap = {};
|
|
113
|
-
|
|
250
|
+
|
|
114
251
|
// Convert from Emscripten val to plain object
|
|
115
252
|
const keys = Object.keys(jsObj);
|
|
116
253
|
for (const key of keys) {
|
|
117
254
|
result[key] = jsObj[key];
|
|
118
255
|
}
|
|
119
|
-
|
|
256
|
+
|
|
120
257
|
return result;
|
|
121
258
|
}
|
|
122
259
|
|
|
123
|
-
/**
|
|
124
|
-
* Set properties from a PropertyMap
|
|
125
|
-
*/
|
|
260
|
+
/** @inheritdoc */
|
|
126
261
|
setProperties(properties: PropertyMap): void {
|
|
127
262
|
this.fileHandle.setProperties(properties);
|
|
128
263
|
}
|
|
129
264
|
|
|
130
|
-
/**
|
|
131
|
-
* Get a single property value
|
|
132
|
-
*/
|
|
265
|
+
/** @inheritdoc */
|
|
133
266
|
getProperty(key: string): string | undefined {
|
|
134
267
|
const value = this.fileHandle.getProperty(key);
|
|
135
268
|
return value === "" ? undefined : value;
|
|
136
269
|
}
|
|
137
270
|
|
|
138
|
-
/**
|
|
139
|
-
* Set a single property value
|
|
140
|
-
*/
|
|
271
|
+
/** @inheritdoc */
|
|
141
272
|
setProperty(key: string, value: string): void {
|
|
142
273
|
this.fileHandle.setProperty(key, value);
|
|
143
274
|
}
|
|
144
275
|
|
|
145
|
-
/**
|
|
146
|
-
* Check if this is an MP4 file
|
|
147
|
-
*/
|
|
276
|
+
/** @inheritdoc */
|
|
148
277
|
isMP4(): boolean {
|
|
149
278
|
return this.fileHandle.isMP4();
|
|
150
279
|
}
|
|
151
280
|
|
|
152
|
-
/**
|
|
153
|
-
* Get MP4-specific item
|
|
154
|
-
*/
|
|
281
|
+
/** @inheritdoc */
|
|
155
282
|
getMP4Item(key: string): string | undefined {
|
|
156
283
|
if (!this.isMP4()) {
|
|
157
284
|
throw new Error("Not an MP4 file");
|
|
@@ -160,9 +287,7 @@ export class AudioFileImpl implements AudioFile {
|
|
|
160
287
|
return value === "" ? undefined : value;
|
|
161
288
|
}
|
|
162
289
|
|
|
163
|
-
/**
|
|
164
|
-
* Set MP4-specific item
|
|
165
|
-
*/
|
|
290
|
+
/** @inheritdoc */
|
|
166
291
|
setMP4Item(key: string, value: string): void {
|
|
167
292
|
if (!this.isMP4()) {
|
|
168
293
|
throw new Error("Not an MP4 file");
|
|
@@ -170,9 +295,7 @@ export class AudioFileImpl implements AudioFile {
|
|
|
170
295
|
this.fileHandle.setMP4Item(key, value);
|
|
171
296
|
}
|
|
172
297
|
|
|
173
|
-
/**
|
|
174
|
-
* Remove MP4-specific item
|
|
175
|
-
*/
|
|
298
|
+
/** @inheritdoc */
|
|
176
299
|
removeMP4Item(key: string): void {
|
|
177
300
|
if (!this.isMP4()) {
|
|
178
301
|
throw new Error("Not an MP4 file");
|
|
@@ -180,26 +303,22 @@ export class AudioFileImpl implements AudioFile {
|
|
|
180
303
|
this.fileHandle.removeMP4Item(key);
|
|
181
304
|
}
|
|
182
305
|
|
|
183
|
-
/**
|
|
184
|
-
* Save changes to the file
|
|
185
|
-
*/
|
|
306
|
+
/** @inheritdoc */
|
|
186
307
|
save(): boolean {
|
|
187
308
|
// Clear caches since values may have changed
|
|
188
309
|
this.cachedTag = null;
|
|
189
310
|
this.cachedAudioProperties = null;
|
|
190
|
-
|
|
311
|
+
|
|
191
312
|
return this.fileHandle.save();
|
|
192
313
|
}
|
|
193
314
|
|
|
194
|
-
/**
|
|
195
|
-
* Get the current file buffer after modifications
|
|
196
|
-
*/
|
|
315
|
+
/** @inheritdoc */
|
|
197
316
|
getFileBuffer(): Uint8Array {
|
|
198
317
|
const bufferString = this.fileHandle.getBuffer();
|
|
199
318
|
if (!bufferString) {
|
|
200
319
|
return new Uint8Array(0);
|
|
201
320
|
}
|
|
202
|
-
|
|
321
|
+
|
|
203
322
|
// Convert string to Uint8Array
|
|
204
323
|
const buffer = new Uint8Array(bufferString.length);
|
|
205
324
|
for (let i = 0; i < bufferString.length; i++) {
|
|
@@ -208,16 +327,12 @@ export class AudioFileImpl implements AudioFile {
|
|
|
208
327
|
return buffer;
|
|
209
328
|
}
|
|
210
329
|
|
|
211
|
-
/**
|
|
212
|
-
* Check if the file is valid
|
|
213
|
-
*/
|
|
330
|
+
/** @inheritdoc */
|
|
214
331
|
isValid(): boolean {
|
|
215
332
|
return this.fileHandle.isValid();
|
|
216
333
|
}
|
|
217
334
|
|
|
218
|
-
/**
|
|
219
|
-
* Free resources
|
|
220
|
-
*/
|
|
335
|
+
/** @inheritdoc */
|
|
221
336
|
dispose(): void {
|
|
222
337
|
if (this.fileHandle) {
|
|
223
338
|
// Embind will handle cleanup when the object goes out of scope
|
|
@@ -230,7 +345,25 @@ export class AudioFileImpl implements AudioFile {
|
|
|
230
345
|
}
|
|
231
346
|
|
|
232
347
|
/**
|
|
233
|
-
* Main TagLib interface
|
|
348
|
+
* Main TagLib interface for audio metadata operations.
|
|
349
|
+
* Provides methods to open audio files and access TagLib functionality.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* ```typescript
|
|
353
|
+
* // Option 1: Auto-initialize
|
|
354
|
+
* const taglib = await TagLib.initialize();
|
|
355
|
+
*
|
|
356
|
+
* // Option 2: Manual initialization
|
|
357
|
+
* import { loadTagLibModule } from "taglib-wasm";
|
|
358
|
+
* const module = await loadTagLibModule();
|
|
359
|
+
* const taglib = new TagLib(module);
|
|
360
|
+
*
|
|
361
|
+
* // Open and process a file
|
|
362
|
+
* const file = await taglib.openFile(audioBuffer);
|
|
363
|
+
* const tag = file.tag();
|
|
364
|
+
* console.log(`Title: ${tag.title}`);
|
|
365
|
+
* file.dispose();
|
|
366
|
+
* ```
|
|
234
367
|
*/
|
|
235
368
|
export class TagLib {
|
|
236
369
|
private module: TagLibModule;
|
|
@@ -240,7 +373,16 @@ export class TagLib {
|
|
|
240
373
|
}
|
|
241
374
|
|
|
242
375
|
/**
|
|
243
|
-
* Initialize TagLib with default configuration
|
|
376
|
+
* Initialize TagLib with default configuration.
|
|
377
|
+
* This is the recommended way to create a TagLib instance.
|
|
378
|
+
*
|
|
379
|
+
* @returns Promise resolving to initialized TagLib instance
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```typescript
|
|
383
|
+
* const taglib = await TagLib.initialize();
|
|
384
|
+
* const file = await taglib.openFile(buffer);
|
|
385
|
+
* ```
|
|
244
386
|
*/
|
|
245
387
|
static async initialize(): Promise<TagLib> {
|
|
246
388
|
// Use the loadTagLibModule function
|
|
@@ -250,31 +392,53 @@ export class TagLib {
|
|
|
250
392
|
}
|
|
251
393
|
|
|
252
394
|
/**
|
|
253
|
-
* Open
|
|
395
|
+
* Open an audio file from a buffer.
|
|
396
|
+
* Automatically detects the file format based on content.
|
|
397
|
+
*
|
|
398
|
+
* @param buffer - Audio file data as ArrayBuffer or typed array
|
|
399
|
+
* @returns Promise resolving to AudioFile instance
|
|
400
|
+
* @throws {Error} If the file format is invalid or unsupported
|
|
401
|
+
* @throws {Error} If the module is not properly initialized
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* // From ArrayBuffer
|
|
406
|
+
* const file = await taglib.openFile(arrayBuffer);
|
|
407
|
+
*
|
|
408
|
+
* // From Uint8Array
|
|
409
|
+
* const uint8Array = new Uint8Array(buffer);
|
|
410
|
+
* const file = await taglib.openFile(uint8Array.buffer);
|
|
411
|
+
*
|
|
412
|
+
* // Remember to dispose when done
|
|
413
|
+
* file.dispose();
|
|
414
|
+
* ```
|
|
254
415
|
*/
|
|
255
416
|
async openFile(buffer: ArrayBuffer): Promise<AudioFile> {
|
|
256
417
|
// Check if Embind is available
|
|
257
418
|
if (!this.module.createFileHandle) {
|
|
258
|
-
throw new Error(
|
|
419
|
+
throw new Error(
|
|
420
|
+
"TagLib module not properly initialized - createFileHandle not found",
|
|
421
|
+
);
|
|
259
422
|
}
|
|
260
|
-
|
|
423
|
+
|
|
261
424
|
// Convert ArrayBuffer to Uint8Array for Embind
|
|
262
425
|
const uint8Array = new Uint8Array(buffer);
|
|
263
|
-
|
|
426
|
+
|
|
264
427
|
// Create a new FileHandle
|
|
265
428
|
const fileHandle = this.module.createFileHandle();
|
|
266
|
-
|
|
429
|
+
|
|
267
430
|
// Load the buffer - Embind should handle Uint8Array conversion
|
|
268
431
|
const success = fileHandle.loadFromBuffer(uint8Array);
|
|
269
432
|
if (!success) {
|
|
270
433
|
throw new Error("Failed to load file from buffer");
|
|
271
434
|
}
|
|
272
|
-
|
|
435
|
+
|
|
273
436
|
return new AudioFileImpl(this.module, fileHandle);
|
|
274
437
|
}
|
|
275
438
|
|
|
276
439
|
/**
|
|
277
|
-
* Get version
|
|
440
|
+
* Get the TagLib version.
|
|
441
|
+
* @returns Version string (e.g., "2.1.0")
|
|
278
442
|
*/
|
|
279
443
|
version(): string {
|
|
280
444
|
return "2.1.0"; // TagLib version we're using
|
|
@@ -282,8 +446,20 @@ export class TagLib {
|
|
|
282
446
|
}
|
|
283
447
|
|
|
284
448
|
/**
|
|
285
|
-
* Create a TagLib instance
|
|
449
|
+
* Create a TagLib instance from a pre-loaded Wasm module.
|
|
450
|
+
* For advanced users who need custom module configuration.
|
|
451
|
+
*
|
|
452
|
+
* @param module - Pre-loaded Wasm module from loadTagLibModule()
|
|
453
|
+
* @returns Promise resolving to TagLib instance
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```typescript
|
|
457
|
+
* import { loadTagLibModule, createTagLib } from "taglib-wasm";
|
|
458
|
+
*
|
|
459
|
+
* const module = await loadTagLibModule();
|
|
460
|
+
* const taglib = await createTagLib(module);
|
|
461
|
+
* ```
|
|
286
462
|
*/
|
|
287
463
|
export async function createTagLib(module: WasmModule): Promise<TagLib> {
|
|
288
464
|
return new TagLib(module);
|
|
289
|
-
}
|
|
465
|
+
}
|