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/types.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview TypeScript type definitions for taglib-wasm
|
|
3
|
+
*
|
|
4
|
+
* This module contains all the type definitions used throughout
|
|
5
|
+
* the taglib-wasm library, including metadata structures,
|
|
6
|
+
* audio properties, and format-specific mappings.
|
|
7
|
+
*
|
|
8
|
+
* @module taglib-wasm/types
|
|
3
9
|
*/
|
|
4
10
|
|
|
5
11
|
// Re-export commonly used classes from other modules
|
|
@@ -7,12 +13,32 @@ export type { TagLibModule } from "./wasm.ts";
|
|
|
7
13
|
// Note: AudioFile is not needed for JSR exports
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
|
-
* Supported file types
|
|
16
|
+
* Supported file types detected by TagLib.
|
|
17
|
+
* "UNKNOWN" indicates the format could not be determined.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const file = await taglib.openFile(buffer);
|
|
22
|
+
* const format = file.getFormat();
|
|
23
|
+
* if (format === "MP3") {
|
|
24
|
+
* // Handle MP3-specific features
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
11
27
|
*/
|
|
12
|
-
export type FileType =
|
|
28
|
+
export type FileType =
|
|
29
|
+
| "MP3"
|
|
30
|
+
| "MP4"
|
|
31
|
+
| "FLAC"
|
|
32
|
+
| "OGG"
|
|
33
|
+
| "OPUS"
|
|
34
|
+
| "WAV"
|
|
35
|
+
| "AIFF"
|
|
36
|
+
| "UNKNOWN";
|
|
13
37
|
|
|
14
38
|
/**
|
|
15
|
-
* Audio format types supported by TagLib
|
|
39
|
+
* Audio format types supported by TagLib.
|
|
40
|
+
* More comprehensive than FileType, includes additional formats
|
|
41
|
+
* that TagLib can read but may have limited support.
|
|
16
42
|
*/
|
|
17
43
|
export type AudioFormat =
|
|
18
44
|
| "MP3"
|
|
@@ -34,7 +60,16 @@ export type AudioFormat =
|
|
|
34
60
|
| "XM";
|
|
35
61
|
|
|
36
62
|
/**
|
|
37
|
-
* Audio properties containing technical information about the file
|
|
63
|
+
* Audio properties containing technical information about the file.
|
|
64
|
+
* All properties are read-only and represent the actual audio stream data.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const props = file.audioProperties();
|
|
69
|
+
* console.log(`Duration: ${props.length} seconds`);
|
|
70
|
+
* console.log(`Bitrate: ${props.bitrate} kbps`);
|
|
71
|
+
* console.log(`Sample rate: ${props.sampleRate} Hz`);
|
|
72
|
+
* ```
|
|
38
73
|
*/
|
|
39
74
|
export interface AudioProperties {
|
|
40
75
|
/** Length of the audio in seconds */
|
|
@@ -48,7 +83,20 @@ export interface AudioProperties {
|
|
|
48
83
|
}
|
|
49
84
|
|
|
50
85
|
/**
|
|
51
|
-
* Basic metadata tags
|
|
86
|
+
* Basic metadata tags common to all audio formats.
|
|
87
|
+
* These are the standard fields supported by most audio files.
|
|
88
|
+
* All fields are optional as not all formats support all fields.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const tag: Tag = {
|
|
93
|
+
* title: "Song Title",
|
|
94
|
+
* artist: "Artist Name",
|
|
95
|
+
* album: "Album Name",
|
|
96
|
+
* year: 2025,
|
|
97
|
+
* track: 5
|
|
98
|
+
* };
|
|
99
|
+
* ```
|
|
52
100
|
*/
|
|
53
101
|
export interface Tag {
|
|
54
102
|
/** Track title */
|
|
@@ -68,7 +116,21 @@ export interface Tag {
|
|
|
68
116
|
}
|
|
69
117
|
|
|
70
118
|
/**
|
|
71
|
-
* Extended metadata with format-agnostic field names
|
|
119
|
+
* Extended metadata with format-agnostic field names.
|
|
120
|
+
* Includes advanced fields like MusicBrainz IDs, ReplayGain values,
|
|
121
|
+
* and other specialized metadata. Field availability depends on
|
|
122
|
+
* the audio format and existing metadata.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const extTag: ExtendedTag = {
|
|
127
|
+
* ...basicTag,
|
|
128
|
+
* albumArtist: "Various Artists",
|
|
129
|
+
* musicbrainzTrackId: "123e4567-e89b-12d3-a456-426614174000",
|
|
130
|
+
* replayGainTrackGain: "-6.54 dB",
|
|
131
|
+
* bpm: 120
|
|
132
|
+
* };
|
|
133
|
+
* ```
|
|
72
134
|
*/
|
|
73
135
|
export interface ExtendedTag extends Tag {
|
|
74
136
|
/** AcoustID fingerprint (Chromaprint) */
|
|
@@ -120,7 +182,19 @@ export interface ExtendedTag extends Tag {
|
|
|
120
182
|
}
|
|
121
183
|
|
|
122
184
|
/**
|
|
123
|
-
* Format-specific field mapping for automatic tag mapping
|
|
185
|
+
* Format-specific field mapping for automatic tag mapping.
|
|
186
|
+
* Defines how a metadata field maps to different audio formats.
|
|
187
|
+
* Used internally for format-agnostic metadata operations.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const artistMapping: FieldMapping = {
|
|
192
|
+
* id3v2: { frame: "TPE1" },
|
|
193
|
+
* vorbis: "ARTIST",
|
|
194
|
+
* mp4: "©ART",
|
|
195
|
+
* wav: "IART"
|
|
196
|
+
* };
|
|
197
|
+
* ```
|
|
124
198
|
*/
|
|
125
199
|
export interface FieldMapping {
|
|
126
200
|
/** MP3 ID3v2 mapping */
|
|
@@ -137,7 +211,19 @@ export interface FieldMapping {
|
|
|
137
211
|
}
|
|
138
212
|
|
|
139
213
|
/**
|
|
140
|
-
* Complete metadata field mappings for all formats
|
|
214
|
+
* Complete metadata field mappings for all formats.
|
|
215
|
+
* This constant defines how each ExtendedTag field maps to
|
|
216
|
+
* format-specific metadata fields across different audio formats.
|
|
217
|
+
* Used for automatic tag mapping in format-agnostic operations.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* // Get the ID3v2 frame for the artist field
|
|
222
|
+
* const artistFrame = METADATA_MAPPINGS.artist.id3v2?.frame; // "TPE1"
|
|
223
|
+
*
|
|
224
|
+
* // Get the Vorbis comment field for album artist
|
|
225
|
+
* const vorbisField = METADATA_MAPPINGS.albumArtist.vorbis; // "ALBUMARTIST"
|
|
226
|
+
* ```
|
|
141
227
|
*/
|
|
142
228
|
export const METADATA_MAPPINGS: Record<keyof ExtendedTag, FieldMapping> = {
|
|
143
229
|
// Basic fields (already handled by TagLib's standard API)
|
|
@@ -297,14 +383,41 @@ export const METADATA_MAPPINGS: Record<keyof ExtendedTag, FieldMapping> = {
|
|
|
297
383
|
};
|
|
298
384
|
|
|
299
385
|
/**
|
|
300
|
-
* Extended metadata properties map
|
|
386
|
+
* Extended metadata properties map.
|
|
387
|
+
* A flexible key-value structure where each key can have multiple values.
|
|
388
|
+
* Used for accessing all metadata in a file, including non-standard fields.
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```typescript
|
|
392
|
+
* const properties: PropertyMap = {
|
|
393
|
+
* "ARTIST": ["Artist Name"],
|
|
394
|
+
* "ALBUMARTIST": ["Album Artist"],
|
|
395
|
+
* "MUSICBRAINZ_TRACKID": ["123e4567-e89b-12d3-a456-426614174000"]
|
|
396
|
+
* };
|
|
397
|
+
* ```
|
|
301
398
|
*/
|
|
302
399
|
export interface PropertyMap {
|
|
303
400
|
[key: string]: string[];
|
|
304
401
|
}
|
|
305
402
|
|
|
306
403
|
/**
|
|
307
|
-
*
|
|
404
|
+
* Re-export TagName type from constants
|
|
405
|
+
*/
|
|
406
|
+
export type { TagName } from "./constants.ts";
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Picture/artwork data embedded in audio files.
|
|
410
|
+
* Represents album art, artist photos, or other images.
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* const picture: Picture = {
|
|
415
|
+
* mimeType: "image/jpeg",
|
|
416
|
+
* data: new Uint8Array(imageBuffer),
|
|
417
|
+
* type: PictureType.FrontCover,
|
|
418
|
+
* description: "Album cover"
|
|
419
|
+
* };
|
|
420
|
+
* ```
|
|
308
421
|
*/
|
|
309
422
|
export interface Picture {
|
|
310
423
|
/** MIME type of the image */
|
|
@@ -318,7 +431,19 @@ export interface Picture {
|
|
|
318
431
|
}
|
|
319
432
|
|
|
320
433
|
/**
|
|
321
|
-
* Picture types as defined by ID3v2 APIC frame
|
|
434
|
+
* Picture types as defined by ID3v2 APIC frame.
|
|
435
|
+
* Standard picture type codes used across different formats
|
|
436
|
+
* to categorize embedded images.
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```typescript
|
|
440
|
+
* // Set front cover art
|
|
441
|
+
* const coverArt = {
|
|
442
|
+
* type: PictureType.FrontCover,
|
|
443
|
+
* mimeType: "image/jpeg",
|
|
444
|
+
* data: imageData
|
|
445
|
+
* };
|
|
446
|
+
* ```
|
|
322
447
|
*/
|
|
323
448
|
export enum PictureType {
|
|
324
449
|
Other = 0,
|
|
@@ -345,16 +470,24 @@ export enum PictureType {
|
|
|
345
470
|
}
|
|
346
471
|
|
|
347
472
|
/**
|
|
348
|
-
* Bitrate control modes for audio encoding (MP4/M4A specific)
|
|
473
|
+
* Bitrate control modes for audio encoding (MP4/M4A specific).
|
|
474
|
+
* Indicates how the audio was encoded in terms of bitrate management.
|
|
475
|
+
*
|
|
476
|
+
* - Constant: Fixed bitrate throughout the file
|
|
477
|
+
* - LongTermAverage: Average bitrate over time
|
|
478
|
+
* - VariableConstrained: Variable within limits
|
|
479
|
+
* - Variable: Fully variable bitrate
|
|
349
480
|
*/
|
|
350
|
-
export type BitrateControlMode =
|
|
481
|
+
export type BitrateControlMode =
|
|
351
482
|
| "Constant"
|
|
352
|
-
| "LongTermAverage"
|
|
483
|
+
| "LongTermAverage"
|
|
353
484
|
| "VariableConstrained"
|
|
354
485
|
| "Variable";
|
|
355
486
|
|
|
356
487
|
/**
|
|
357
|
-
* Map of bitrate control mode names to their numeric values
|
|
488
|
+
* Map of bitrate control mode names to their numeric values.
|
|
489
|
+
* Used for converting between string representations and numeric codes
|
|
490
|
+
* stored in MP4/M4A files.
|
|
358
491
|
*/
|
|
359
492
|
export const BITRATE_CONTROL_MODE_VALUES: Record<BitrateControlMode, number> = {
|
|
360
493
|
Constant: 0,
|
|
@@ -364,7 +497,9 @@ export const BITRATE_CONTROL_MODE_VALUES: Record<BitrateControlMode, number> = {
|
|
|
364
497
|
};
|
|
365
498
|
|
|
366
499
|
/**
|
|
367
|
-
* Map of numeric values to bitrate control mode names
|
|
500
|
+
* Map of numeric values to bitrate control mode names.
|
|
501
|
+
* Used for converting numeric codes from MP4/M4A files
|
|
502
|
+
* to human-readable string representations.
|
|
368
503
|
*/
|
|
369
504
|
export const BITRATE_CONTROL_MODE_NAMES: Record<number, BitrateControlMode> = {
|
|
370
505
|
0: "Constant",
|
|
@@ -374,7 +509,21 @@ export const BITRATE_CONTROL_MODE_NAMES: Record<number, BitrateControlMode> = {
|
|
|
374
509
|
};
|
|
375
510
|
|
|
376
511
|
/**
|
|
377
|
-
* Configuration options for TagLib initialization
|
|
512
|
+
* Configuration options for TagLib initialization.
|
|
513
|
+
* Allows customization of memory limits and debug settings.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```typescript
|
|
517
|
+
* const config: TagLibConfig = {
|
|
518
|
+
* memory: {
|
|
519
|
+
* initial: 16 * 1024 * 1024, // 16MB
|
|
520
|
+
* maximum: 64 * 1024 * 1024 // 64MB
|
|
521
|
+
* },
|
|
522
|
+
* debug: true
|
|
523
|
+
* };
|
|
524
|
+
*
|
|
525
|
+
* const taglib = await TagLibWorkers.initialize(wasmBinary, config);
|
|
526
|
+
* ```
|
|
378
527
|
*/
|
|
379
528
|
export interface TagLibConfig {
|
|
380
529
|
/** Memory allocation settings */
|
package/src/wasm-workers.ts
CHANGED
|
@@ -23,7 +23,7 @@ const DEFAULT_WORKERS_CONFIG: Required<TagLibConfig> = {
|
|
|
23
23
|
* Load and initialize the TagLib WebAssembly module for Cloudflare Workers
|
|
24
24
|
*
|
|
25
25
|
* @param wasmBinary - The WebAssembly binary as Uint8Array
|
|
26
|
-
* @param config - Optional configuration for the
|
|
26
|
+
* @param config - Optional configuration for the Wasm module
|
|
27
27
|
* @returns Promise resolving to initialized TagLib module
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
@@ -66,13 +66,13 @@ export async function loadTagLibModuleForWorkers(
|
|
|
66
66
|
try {
|
|
67
67
|
// For Workers, we need to use a modified version of the Emscripten output
|
|
68
68
|
// that doesn't include Node.js/CommonJS dependencies
|
|
69
|
-
const
|
|
69
|
+
const TagLibWasm = await createWorkersCompatibleModule();
|
|
70
70
|
|
|
71
|
-
if (typeof
|
|
71
|
+
if (typeof TagLibWasm !== "function") {
|
|
72
72
|
throw new Error("Failed to load taglib-wasm module for Workers");
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const wasmInstance = await
|
|
75
|
+
const wasmInstance = await TagLibWasm(moduleConfig);
|
|
76
76
|
|
|
77
77
|
// Ensure proper memory arrays are set up
|
|
78
78
|
if (!wasmInstance.HEAPU8) {
|
|
@@ -99,7 +99,7 @@ export async function loadTagLibModuleForWorkers(
|
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* Create a Workers-compatible version of the Emscripten module
|
|
102
|
-
* This function loads the
|
|
102
|
+
* This function loads the Wasm module without Node.js/CommonJS dependencies
|
|
103
103
|
*/
|
|
104
104
|
async function createWorkersCompatibleModule(): Promise<any> {
|
|
105
105
|
// In a real Workers environment, you would typically:
|
|
@@ -115,8 +115,8 @@ async function createWorkersCompatibleModule(): Promise<any> {
|
|
|
115
115
|
} catch (error) {
|
|
116
116
|
// If that fails, provide a fallback implementation
|
|
117
117
|
throw new Error(
|
|
118
|
-
"Workers-compatible
|
|
119
|
-
"Please build with Workers target or use a bundler that supports
|
|
118
|
+
"Workers-compatible Wasm module not available. " +
|
|
119
|
+
"Please build with Workers target or use a bundler that supports Wasm modules. " +
|
|
120
120
|
`Original error: ${(error as Error).message}`,
|
|
121
121
|
);
|
|
122
122
|
}
|
|
@@ -141,7 +141,7 @@ export function cStringToJS(module: TagLibModule, ptr: number): string {
|
|
|
141
141
|
export function jsToCString(module: TagLibModule, str: string): number {
|
|
142
142
|
const encoder = new TextEncoder();
|
|
143
143
|
const bytes = encoder.encode(str + "\0");
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
// Use allocate if available, otherwise use _malloc
|
|
146
146
|
if (module.allocate && module.ALLOC_NORMAL !== undefined) {
|
|
147
147
|
return module.allocate(bytes, module.ALLOC_NORMAL);
|
package/src/wasm.ts
CHANGED
|
@@ -13,20 +13,29 @@ export interface EmscriptenModule {
|
|
|
13
13
|
HEAPU32: Uint32Array;
|
|
14
14
|
HEAPF32: Float32Array;
|
|
15
15
|
HEAPF64: Float64Array;
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
// Memory management
|
|
18
18
|
_malloc(size: number): number;
|
|
19
19
|
_free(ptr: number): void;
|
|
20
20
|
allocate?(data: number[] | Uint8Array, allocator: number): number;
|
|
21
21
|
ALLOC_NORMAL?: number;
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
// String conversion
|
|
24
|
-
ccall?(
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
ccall?(
|
|
25
|
+
ident: string,
|
|
26
|
+
returnType: string,
|
|
27
|
+
argTypes: string[],
|
|
28
|
+
args: any[],
|
|
29
|
+
): any;
|
|
30
|
+
cwrap?(
|
|
31
|
+
ident: string,
|
|
32
|
+
returnType: string,
|
|
33
|
+
argTypes: string[],
|
|
34
|
+
): (...args: any[]) => any;
|
|
35
|
+
|
|
27
36
|
// File system (if enabled)
|
|
28
37
|
FS?: any;
|
|
29
|
-
|
|
38
|
+
|
|
30
39
|
// Runtime
|
|
31
40
|
then?(callback: (module: EmscriptenModule) => void): void;
|
|
32
41
|
onRuntimeInitialized?: () => void;
|
|
@@ -80,10 +89,10 @@ export interface TagLibModule extends EmscriptenModule {
|
|
|
80
89
|
FileHandle: new () => FileHandle;
|
|
81
90
|
TagWrapper: new () => TagWrapper;
|
|
82
91
|
AudioPropertiesWrapper: new () => AudioPropertiesWrapper;
|
|
83
|
-
|
|
92
|
+
|
|
84
93
|
// Embind functions
|
|
85
94
|
createFileHandle(): FileHandle;
|
|
86
|
-
|
|
95
|
+
|
|
87
96
|
// C-style functions (optional - used by Workers API)
|
|
88
97
|
_taglib_file_new_from_buffer?(ptr: number, size: number): number;
|
|
89
98
|
_taglib_file_delete?(fileId: number): void;
|
|
@@ -92,7 +101,7 @@ export interface TagLibModule extends EmscriptenModule {
|
|
|
92
101
|
_taglib_file_tag?(fileId: number): number;
|
|
93
102
|
_taglib_file_audioproperties?(fileId: number): number;
|
|
94
103
|
_taglib_file_save?(fileId: number): number;
|
|
95
|
-
|
|
104
|
+
|
|
96
105
|
_taglib_tag_title?(tagPtr: number): number;
|
|
97
106
|
_taglib_tag_artist?(tagPtr: number): number;
|
|
98
107
|
_taglib_tag_album?(tagPtr: number): number;
|
|
@@ -100,7 +109,7 @@ export interface TagLibModule extends EmscriptenModule {
|
|
|
100
109
|
_taglib_tag_genre?(tagPtr: number): number;
|
|
101
110
|
_taglib_tag_year?(tagPtr: number): number;
|
|
102
111
|
_taglib_tag_track?(tagPtr: number): number;
|
|
103
|
-
|
|
112
|
+
|
|
104
113
|
_taglib_tag_set_title?(tagPtr: number, titlePtr: number): void;
|
|
105
114
|
_taglib_tag_set_artist?(tagPtr: number, artistPtr: number): void;
|
|
106
115
|
_taglib_tag_set_album?(tagPtr: number, albumPtr: number): void;
|
|
@@ -108,7 +117,7 @@ export interface TagLibModule extends EmscriptenModule {
|
|
|
108
117
|
_taglib_tag_set_genre?(tagPtr: number, genrePtr: number): void;
|
|
109
118
|
_taglib_tag_set_year?(tagPtr: number, year: number): void;
|
|
110
119
|
_taglib_tag_set_track?(tagPtr: number, track: number): void;
|
|
111
|
-
|
|
120
|
+
|
|
112
121
|
_taglib_audioproperties_length?(propsPtr: number): number;
|
|
113
122
|
_taglib_audioproperties_bitrate?(propsPtr: number): number;
|
|
114
123
|
_taglib_audioproperties_samplerate?(propsPtr: number): number;
|
|
@@ -121,4 +130,4 @@ export interface WasmModule extends EmscriptenModule {
|
|
|
121
130
|
createFileHandle?(): FileHandle;
|
|
122
131
|
}
|
|
123
132
|
|
|
124
|
-
// Module loading function removed for modular imports
|
|
133
|
+
// Module loading function removed for modular imports
|