taglib-wasm 0.2.8 β†’ 0.3.1

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 CHANGED
@@ -26,7 +26,7 @@ Because there’s nothing like it. [`mp3tag.js`](https://mp3tag.js.org/) is matu
26
26
  ### Deno
27
27
 
28
28
  ```typescript
29
- import { TagLib } from "jsr:@charleswiltgen/taglib-wasm";
29
+ import { TagLib } from "npm:taglib-wasm";
30
30
  ```
31
31
 
32
32
  ### Node.js
@@ -78,13 +78,13 @@ console.log(`Duration: ${props.length}s, Bitrate: ${props.bitrate} kbps`);
78
78
  Full control when you need it:
79
79
 
80
80
  ```typescript
81
- import { TagLib } from "jsr:@charleswiltgen/taglib-wasm";
81
+ import { TagLib } from "taglib-wasm";
82
82
 
83
83
  // Initialize taglib-wasm
84
84
  const taglib = await TagLib.initialize();
85
85
 
86
86
  // Load audio file from buffer
87
- const audioData = await Deno.readFile("song.mp3");
87
+ const audioData = await readFile("song.mp3"); // Node.js/Bun: fs.readFile, Deno: Deno.readFile
88
88
  const file = taglib.openFile(audioData);
89
89
 
90
90
  // Read metadata
@@ -97,16 +97,15 @@ console.log(`Duration: ${props.length}s`);
97
97
  console.log(`Bitrate: ${props.bitrate} kbps`);
98
98
 
99
99
  // Write metadata
100
- file.setTitle("New Title");
101
- file.setArtist("New Artist");
102
- file.setAlbum("New Album");
100
+ const tag = file.tag();
101
+ tag.setTitle("New Title");
102
+ tag.setArtist("New Artist");
103
+ tag.setAlbum("New Album");
103
104
 
104
- console.log("Updated tags:", file.tag());
105
+ // Save changes
106
+ file.save();
105
107
 
106
- // Automatic tag mapping (format-agnostic)
107
- file.setAcoustidFingerprint("AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
108
- file.setAcoustidId("e7359e88-f1f7-41ed-b9f6-16e58e906997");
109
- file.setMusicBrainzTrackId("f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
108
+ console.log("Updated tags:", file.tag());
110
109
 
111
110
  // Clean up
112
111
  file.dispose();
@@ -137,16 +136,15 @@ console.log(`Duration: ${props.length}s`);
137
136
  console.log(`Bitrate: ${props.bitrate} kbps`);
138
137
 
139
138
  // Write metadata
140
- file.setTitle("New Title");
141
- file.setArtist("New Artist");
142
- file.setAlbum("New Album");
139
+ const tag = file.tag();
140
+ tag.setTitle("New Title");
141
+ tag.setArtist("New Artist");
142
+ tag.setAlbum("New Album");
143
143
 
144
- console.log("Updated tags:", file.tag());
144
+ // Save changes
145
+ file.save();
145
146
 
146
- // Automatic tag mapping (format-agnostic)
147
- file.setAcoustidFingerprint("AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
148
- file.setAcoustidId("e7359e88-f1f7-41ed-b9f6-16e58e906997");
149
- file.setMusicBrainzTrackId("f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
147
+ console.log("Updated tags:", file.tag());
150
148
 
151
149
  // Clean up
152
150
  file.dispose();
@@ -174,16 +172,15 @@ console.log(`Duration: ${props.length}s`);
174
172
  console.log(`Bitrate: ${props.bitrate} kbps`);
175
173
 
176
174
  // Write metadata
177
- file.setTitle("New Title");
178
- file.setArtist("New Artist");
179
- file.setAlbum("New Album");
175
+ const tag = file.tag();
176
+ tag.setTitle("New Title");
177
+ tag.setArtist("New Artist");
178
+ tag.setAlbum("New Album");
180
179
 
181
- console.log("Updated tags:", file.tag());
180
+ // Save changes
181
+ file.save();
182
182
 
183
- // Automatic tag mapping (format-agnostic)
184
- file.setAcoustidFingerprint("AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
185
- file.setAcoustidId("e7359e88-f1f7-41ed-b9f6-16e58e906997");
186
- file.setMusicBrainzTrackId("f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
183
+ console.log("Updated tags:", file.tag());
187
184
 
188
185
  // Clean up
189
186
  file.dispose();
@@ -213,16 +210,51 @@ console.log(`Duration: ${props.length}s`);
213
210
  console.log(`Bitrate: ${props.bitrate} kbps`);
214
211
 
215
212
  // Write metadata
216
- file.setTitle("New Title");
217
- file.setArtist("New Artist");
218
- file.setAlbum("New Album");
213
+ const tag = file.tag();
214
+ tag.setTitle("New Title");
215
+ tag.setArtist("New Artist");
216
+ tag.setAlbum("New Album");
217
+
218
+ // Save changes
219
+ file.save();
219
220
 
220
221
  console.log("Updated tags:", file.tag());
221
222
 
222
- // Automatic tag mapping (format-agnostic)
223
- file.setAcoustidFingerprint("AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
224
- file.setAcoustidId("e7359e88-f1f7-41ed-b9f6-16e58e906997");
225
- file.setMusicBrainzTrackId("f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
223
+ // Clean up
224
+ file.dispose();
225
+ ```
226
+
227
+ ### Deno
228
+
229
+ ```typescript
230
+ import { TagLib } from "npm:taglib-wasm";
231
+
232
+ // Initialize taglib-wasm
233
+ const taglib = await TagLib.initialize();
234
+
235
+ // Load audio file from filesystem
236
+ const audioData = await Deno.readFile("song.mp3");
237
+ const file = taglib.openFile(audioData);
238
+
239
+ // Read metadata
240
+ const tags = file.tag();
241
+ const props = file.audioProperties();
242
+
243
+ console.log(`Title: ${tags.title}`);
244
+ console.log(`Artist: ${tags.artist}`);
245
+ console.log(`Duration: ${props.length}s`);
246
+ console.log(`Bitrate: ${props.bitrate} kbps`);
247
+
248
+ // Write metadata
249
+ const tag = file.tag();
250
+ tag.setTitle("New Title");
251
+ tag.setArtist("New Artist");
252
+ tag.setAlbum("New Album");
253
+
254
+ // Save changes
255
+ file.save();
256
+
257
+ console.log("Updated tags:", file.tag());
226
258
 
227
259
  // Clean up
228
260
  file.dispose();
@@ -293,63 +325,62 @@ export default {
293
325
  - βœ… **.wav** – INFO chunk metadata
294
326
  - βœ… **Legacy formats**: Opus, APE, MPC, WavPack, TrueAudio, and more
295
327
 
296
- ## 🎯 Automatic Tag Mapping
328
+ ## 🎯 Extended Metadata with PropertyMap
297
329
 
298
- `taglib-wasm` supports **automatic tag mapping** so you don’t have to worry about how the same tag is stored differently in different audio container formats.
330
+ `taglib-wasm` provides a **PropertyMap API** for accessing extended metadata beyond the basic tags. This allows you to read and write format-specific fields and custom metadata.
299
331
 
300
332
  ### AcoustID example
301
333
 
302
334
  ```typescript
303
- // Single API works for ALL formats (MP3, FLAC, OGG, MP4)
304
- file.setAcoustidFingerprint("AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
305
- file.setAcoustidId("e7359e88-f1f7-41ed-b9f6-16e58e906997");
306
-
307
- // Automatically stores in format-specific locations:
308
- // β€’ MP3: TXXX frames with proper descriptions
309
- // β€’ FLAC/OGG: ACOUSTID_FINGERPRINT and ACOUSTID_ID Vorbis comments
310
- // β€’ MP4: ----:com.apple.iTunes:Acoustid... freeform atoms
335
+ // Using PropertyMap API to set extended metadata
336
+ file.setProperty("ACOUSTID_FINGERPRINT", "AQADtMmybfGO8NCNEESLnzHyXNOHeHnG...");
337
+ file.setProperty("ACOUSTID_ID", "e7359e88-f1f7-41ed-b9f6-16e58e906997");
338
+
339
+ // Note: Property keys may vary by format
340
+ // Use file.properties() to see all available properties
341
+ file.save(); // Don't forget to save!
311
342
  ```
312
343
 
313
344
  ### MusicBrainz example
314
345
 
315
346
  ```typescript
316
- // Professional music database integration
317
- file.setMusicBrainzTrackId("f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
318
- file.setMusicBrainzReleaseId("a1b2c3d4-e5f6-7890-abcd-ef1234567890");
319
- file.setMusicBrainzArtistId("12345678-90ab-cdef-1234-567890abcdef");
347
+ // MusicBrainz metadata using PropertyMap
348
+ file.setProperty("MUSICBRAINZ_TRACKID", "f4d1b6b8-8c1e-4d9a-9f2a-1234567890ab");
349
+ file.setProperty("MUSICBRAINZ_ALBUMID", "a1b2c3d4-e5f6-7890-abcd-ef1234567890");
350
+ file.setProperty("MUSICBRAINZ_ARTISTID", "12345678-90ab-cdef-1234-567890abcdef");
320
351
  ```
321
352
 
322
353
  ### Volume example
323
354
 
324
355
  ```typescript
325
- // ReplayGain support (automatic format mapping)
326
- file.setReplayGainTrackGain("-6.54 dB");
327
- file.setReplayGainTrackPeak("0.987654");
328
- file.setReplayGainAlbumGain("-8.12 dB");
329
- file.setReplayGainAlbumPeak("0.995432");
330
-
331
- // Apple Sound Check support
332
- file.setAppleSoundCheck("00000150 00000150 00000150 00000150...");
356
+ // ReplayGain volume normalization
357
+ file.setProperty("REPLAYGAIN_TRACK_GAIN", "-6.54 dB");
358
+ file.setProperty("REPLAYGAIN_TRACK_PEAK", "0.987654");
359
+ file.setProperty("REPLAYGAIN_ALBUM_GAIN", "-8.12 dB");
360
+ file.setProperty("REPLAYGAIN_ALBUM_PEAK", "0.995432");
333
361
  ```
334
362
 
335
363
  ### Extended fields
336
364
 
337
365
  ```typescript
338
- // Advanced metadata fields
339
- file.setExtendedTag({
340
- albumArtist: "Various Artists",
341
- composer: "Composer Name",
342
- bpm: 120,
343
- compilation: true,
344
- discNumber: 1,
345
- totalTracks: 12,
346
- // Volume normalization
347
- replayGainTrackGain: "-6.54 dB",
348
- appleSoundCheck: "00000150...",
366
+ // Using PropertyMap to set multiple properties at once
367
+ const properties = file.properties(); // Get current properties
368
+
369
+ // Set extended metadata
370
+ file.setProperties({
371
+ ALBUMARTIST: ["Various Artists"],
372
+ COMPOSER: ["Composer Name"],
373
+ BPM: ["120"],
374
+ COMPILATION: ["1"],
375
+ DISCNUMBER: ["1"],
376
+ TRACKTOTAL: ["12"],
377
+ // Note: Property keys vary by format
349
378
  });
350
- ```
351
379
 
352
- **πŸ“– See [docs/Automatic-Tag-Mapping.md](docs/Automatic-Tag-Mapping.md) for complete documentation**
380
+ // Or set individual properties
381
+ file.setProperty("ALBUMARTIST", "Various Artists");
382
+ file.setProperty("COMPOSER", "Composer Name");
383
+ ```
353
384
 
354
385
  ## πŸ—οΈ Development
355
386
 
@@ -384,8 +415,7 @@ build/
384
415
  β”œβ”€β”€ taglib.js # Generated Emscripten JavaScript
385
416
  └── taglib.wasm # Compiled WebAssembly module
386
417
 
387
- tests/ # Test files and sample audio files
388
- tests/ # Test suite
418
+ tests/ # Test suite and sample audio files
389
419
  examples/ # Usage examples for different runtimes
390
420
  β”œβ”€β”€ deno/ # Deno-specific examples
391
421
  β”œβ”€β”€ bun/ # Bun-specific examples
@@ -449,53 +479,63 @@ class TagLib {
449
479
  class AudioFile {
450
480
  // Validation
451
481
  isValid(): boolean;
452
- format(): string;
482
+ getFormat(): string;
453
483
 
454
484
  // Properties
455
485
  audioProperties(): AudioProperties;
456
- tag(): TagData;
457
486
 
458
- // Tag Writing
459
- setTitle(title: string): void;
460
- setArtist(artist: string): void;
461
- setAlbum(album: string): void;
462
- setComment(comment: string): void;
463
- setGenre(genre: string): void;
464
- setYear(year: number): void;
465
- setTrack(track: number): void;
487
+ // Tag Access (returns Tag object with getters and setters)
488
+ tag(): Tag;
489
+
490
+ // PropertyMap API for extended metadata
491
+ properties(): PropertyMap;
492
+ setProperties(properties: PropertyMap): void;
493
+ getProperty(key: string): string | undefined;
494
+ setProperty(key: string, value: string): void;
495
+
496
+ // MP4-specific methods
497
+ isMP4(): boolean;
498
+ getMP4Item(key: string): string | undefined;
499
+ setMP4Item(key: string, value: string): void;
500
+ removeMP4Item(key: string): void;
466
501
 
467
502
  // File Operations
468
503
  save(): boolean;
504
+ getFileBuffer(): Uint8Array;
469
505
  dispose(): void;
506
+ }
507
+ ```
470
508
 
471
- // Automatic Tag Mapping (Format-Agnostic)
472
- extendedTag(): ExtendedTag;
473
- setExtendedTag(tag: Partial<ExtendedTag>): void;
474
-
475
- // AcoustID Integration
476
- setAcoustidFingerprint(fingerprint: string): void;
477
- getAcoustidFingerprint(): string | undefined;
478
- setAcoustidId(id: string): void;
479
- getAcoustidId(): string | undefined;
480
-
481
- // MusicBrainz Integration
482
- setMusicBrainzTrackId(id: string): void;
483
- getMusicBrainzTrackId(): string | undefined;
484
-
485
- // Volume Normalization
486
- setReplayGainTrackGain(gain: string): void;
487
- getReplayGainTrackGain(): string | undefined;
488
- setReplayGainTrackPeak(peak: string): void;
489
- getReplayGainTrackPeak(): string | undefined;
490
- setReplayGainAlbumGain(gain: string): void;
491
- getReplayGainAlbumGain(): string | undefined;
492
- setReplayGainAlbumPeak(peak: string): void;
493
- getReplayGainAlbumPeak(): string | undefined;
494
- setAppleSoundCheck(iTunNORM: string): void;
495
- getAppleSoundCheck(): string | undefined;
509
+ ### Tag interface
510
+
511
+ ```typescript
512
+ interface Tag {
513
+ // Basic metadata (getters)
514
+ title: string;
515
+ artist: string;
516
+ album: string;
517
+ comment: string;
518
+ genre: string;
519
+ year: number;
520
+ track: number;
521
+
522
+ // Setters
523
+ setTitle(value: string): void;
524
+ setArtist(value: string): void;
525
+ setAlbum(value: string): void;
526
+ setComment(value: string): void;
527
+ setGenre(value: string): void;
528
+ setYear(value: number): void;
529
+ setTrack(value: number): void;
496
530
  }
497
531
  ```
498
532
 
533
+ ### PropertyMap type
534
+
535
+ ```typescript
536
+ type PropertyMap = { [key: string]: string[] };
537
+ ```
538
+
499
539
  ## πŸŽ›οΈ Configuration
500
540
 
501
541
  ```typescript
@@ -514,7 +554,7 @@ interface TagLibConfig {
514
554
 
515
555
  | Runtime | Status | Installation | Performance | TypeScript |
516
556
  | ----------- | ------- | --------------------------------- | ----------- | ---------- |
517
- | **Deno** | βœ… Full | `jsr:@charleswiltgen/taglib-wasm` | Excellent | Native |
557
+ | **Deno** | βœ… Full | `npm:taglib-wasm` | Excellent | Native |
518
558
  | **Bun** | βœ… Full | `bun add taglib-wasm` | Excellent | Native |
519
559
  | **Node.js** | βœ… Full | `npm install taglib-wasm` | Good | Via loader |
520
560
  | **Browser** | βœ… Full | CDN/bundler | Good | Via build |