taglib-wasm 0.3.13 → 0.3.15
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 +22 -35
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +117 -134
- package/dist/index.js.map +1 -0
- package/dist/src/constants.js +211 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/errors.js +180 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/file-utils.d.ts +2 -2
- package/dist/src/file-utils.d.ts.map +1 -1
- package/dist/src/file-utils.js +394 -0
- package/dist/src/file-utils.js.map +1 -0
- package/dist/src/mod.d.ts +4 -4
- package/dist/src/mod.d.ts.map +1 -1
- package/dist/src/mod.js +7 -0
- package/dist/src/mod.js.map +1 -0
- package/dist/src/simple.d.ts +4 -4
- package/dist/src/simple.d.ts.map +1 -1
- package/dist/src/{simple.ts → simple.js} +193 -311
- package/dist/src/simple.js.map +1 -0
- package/dist/src/taglib.d.ts +3 -3
- package/dist/src/taglib.d.ts.map +1 -1
- package/dist/src/taglib.js +516 -0
- package/dist/src/taglib.js.map +1 -0
- package/dist/src/types.d.ts +2 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +239 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/file.js +65 -0
- package/dist/src/utils/file.js.map +1 -0
- package/dist/src/utils/write.js +49 -0
- package/dist/src/utils/write.js.map +1 -0
- package/dist/src/wasm-workers.d.ts +1 -1
- package/dist/src/wasm-workers.d.ts.map +1 -1
- package/dist/src/wasm-workers.js +148 -0
- package/dist/src/wasm-workers.js.map +1 -0
- package/dist/src/wasm.js +6 -0
- package/dist/src/wasm.js.map +1 -0
- package/dist/src/web-utils.d.ts +2 -2
- package/dist/src/web-utils.d.ts.map +1 -1
- package/{src/web-utils.ts → dist/src/web-utils.js} +102 -184
- package/dist/src/web-utils.js.map +1 -0
- package/dist/src/workers.d.ts +2 -2
- package/dist/src/workers.d.ts.map +1 -1
- package/dist/src/workers.js +389 -0
- package/dist/src/workers.js.map +1 -0
- package/dist/taglib-wrapper.js +8 -2528
- package/package.json +7 -10
- package/dist/index.ts +0 -221
- package/dist/src/constants.ts +0 -227
- package/dist/src/errors.ts +0 -254
- package/dist/src/file-utils.ts +0 -483
- package/dist/src/file.js +0 -52
- package/dist/src/global.d.ts +0 -12
- package/dist/src/mod.ts +0 -19
- package/dist/src/taglib.ts +0 -961
- package/dist/src/types.ts +0 -538
- package/dist/src/utils/file.ts +0 -86
- package/dist/src/utils/write.ts +0 -66
- package/dist/src/wasm-workers.ts +0 -176
- package/dist/src/wasm.ts +0 -133
- package/dist/src/web-utils.ts +0 -347
- package/dist/src/workers.ts +0 -461
- package/dist/src/write.js +0 -33
- package/index.ts +0 -221
- package/lib/taglib/COPYING.LGPL +0 -502
- package/lib/taglib/COPYING.MPL +0 -470
- package/lib/taglib/README.md +0 -24
- package/src/constants.ts +0 -227
- package/src/errors.ts +0 -254
- package/src/file-utils.ts +0 -483
- package/src/global.d.ts +0 -12
- package/src/mod.ts +0 -19
- package/src/simple.ts +0 -667
- package/src/taglib.ts +0 -961
- package/src/types.ts +0 -538
- package/src/utils/file.ts +0 -86
- package/src/utils/write.ts +0 -66
- package/src/wasm-workers.ts +0 -176
- package/src/wasm.ts +0 -133
- package/src/workers.ts +0 -461
|
@@ -29,21 +29,11 @@
|
|
|
29
29
|
* console.log(`Duration: ${props.length}s, Bitrate: ${props.bitrate}kbps`);
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
|
|
33
|
-
import {
|
|
34
|
-
import
|
|
35
|
-
import { PictureType } from "./types.ts";
|
|
36
|
-
import {
|
|
37
|
-
FileOperationError,
|
|
38
|
-
InvalidFormatError,
|
|
39
|
-
MetadataError,
|
|
40
|
-
} from "./errors.ts";
|
|
41
|
-
import { readFileData } from "./utils/file.ts";
|
|
42
|
-
import { writeFileData } from "./utils/write.ts";
|
|
43
|
-
|
|
32
|
+
import { PictureType } from "./types.js";
|
|
33
|
+
import { FileOperationError, InvalidFormatError, MetadataError, } from "./errors.js";
|
|
34
|
+
import { writeFileData } from "./utils/write.js";
|
|
44
35
|
// Cached TagLib instance for auto-initialization
|
|
45
|
-
let cachedTagLib
|
|
46
|
-
|
|
36
|
+
let cachedTagLib = null;
|
|
47
37
|
/**
|
|
48
38
|
* Get or create a TagLib instance with auto-initialization.
|
|
49
39
|
* Uses a cached instance for performance.
|
|
@@ -51,15 +41,14 @@ let cachedTagLib: TagLib | null = null;
|
|
|
51
41
|
* @internal
|
|
52
42
|
* @returns Promise resolving to TagLib instance
|
|
53
43
|
*/
|
|
54
|
-
async function getTagLib()
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
async function getTagLib() {
|
|
45
|
+
if (!cachedTagLib) {
|
|
46
|
+
// Use the NPM version for compatibility
|
|
47
|
+
const { TagLib } = await import("./taglib.js");
|
|
48
|
+
cachedTagLib = await TagLib.initialize();
|
|
49
|
+
}
|
|
50
|
+
return cachedTagLib;
|
|
61
51
|
}
|
|
62
|
-
|
|
63
52
|
/**
|
|
64
53
|
* Read metadata tags from an audio file
|
|
65
54
|
*
|
|
@@ -72,24 +61,19 @@ async function getTagLib(): Promise<TagLib> {
|
|
|
72
61
|
* console.log(tags.title, tags.artist, tags.album);
|
|
73
62
|
* ```
|
|
74
63
|
*/
|
|
75
|
-
export async function readTags(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
64
|
+
export async function readTags(file) {
|
|
65
|
+
const taglib = await getTagLib();
|
|
66
|
+
const audioFile = await taglib.open(file);
|
|
67
|
+
try {
|
|
68
|
+
if (!audioFile.isValid()) {
|
|
69
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
70
|
+
}
|
|
71
|
+
return audioFile.tag();
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
audioFile.dispose();
|
|
85
75
|
}
|
|
86
|
-
|
|
87
|
-
return audioFile.tag();
|
|
88
|
-
} finally {
|
|
89
|
-
audioFile.dispose();
|
|
90
|
-
}
|
|
91
76
|
}
|
|
92
|
-
|
|
93
77
|
/**
|
|
94
78
|
* Apply metadata tags to an audio file and return the modified buffer
|
|
95
79
|
*
|
|
@@ -112,46 +96,40 @@ export async function readTags(
|
|
|
112
96
|
* // Save modifiedBuffer to file or use as needed
|
|
113
97
|
* ```
|
|
114
98
|
*/
|
|
115
|
-
export async function applyTags(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
99
|
+
export async function applyTags(file, tags, options) {
|
|
100
|
+
const taglib = await getTagLib();
|
|
101
|
+
const audioFile = await taglib.open(file);
|
|
102
|
+
try {
|
|
103
|
+
if (!audioFile.isValid()) {
|
|
104
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
105
|
+
}
|
|
106
|
+
// Get the tag object and write each tag if defined
|
|
107
|
+
const tag = audioFile.tag();
|
|
108
|
+
if (tags.title !== undefined)
|
|
109
|
+
tag.setTitle(tags.title);
|
|
110
|
+
if (tags.artist !== undefined)
|
|
111
|
+
tag.setArtist(tags.artist);
|
|
112
|
+
if (tags.album !== undefined)
|
|
113
|
+
tag.setAlbum(tags.album);
|
|
114
|
+
if (tags.comment !== undefined)
|
|
115
|
+
tag.setComment(tags.comment);
|
|
116
|
+
if (tags.genre !== undefined)
|
|
117
|
+
tag.setGenre(tags.genre);
|
|
118
|
+
if (tags.year !== undefined)
|
|
119
|
+
tag.setYear(tags.year);
|
|
120
|
+
if (tags.track !== undefined)
|
|
121
|
+
tag.setTrack(tags.track);
|
|
122
|
+
// Save changes to in-memory buffer
|
|
123
|
+
if (!audioFile.save()) {
|
|
124
|
+
throw new FileOperationError("save", "Failed to save metadata changes. The file may be read-only or corrupted.");
|
|
125
|
+
}
|
|
126
|
+
// Get the modified buffer after saving
|
|
127
|
+
return audioFile.getFileBuffer();
|
|
127
128
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const tag = audioFile.tag();
|
|
131
|
-
if (tags.title !== undefined) tag.setTitle(tags.title);
|
|
132
|
-
if (tags.artist !== undefined) tag.setArtist(tags.artist);
|
|
133
|
-
if (tags.album !== undefined) tag.setAlbum(tags.album);
|
|
134
|
-
if (tags.comment !== undefined) tag.setComment(tags.comment);
|
|
135
|
-
if (tags.genre !== undefined) tag.setGenre(tags.genre);
|
|
136
|
-
if (tags.year !== undefined) tag.setYear(tags.year);
|
|
137
|
-
if (tags.track !== undefined) tag.setTrack(tags.track);
|
|
138
|
-
|
|
139
|
-
// Save changes to in-memory buffer
|
|
140
|
-
if (!audioFile.save()) {
|
|
141
|
-
throw new FileOperationError(
|
|
142
|
-
"save",
|
|
143
|
-
"Failed to save metadata changes. The file may be read-only or corrupted.",
|
|
144
|
-
);
|
|
129
|
+
finally {
|
|
130
|
+
audioFile.dispose();
|
|
145
131
|
}
|
|
146
|
-
|
|
147
|
-
// Get the modified buffer after saving
|
|
148
|
-
return audioFile.getFileBuffer();
|
|
149
|
-
} finally {
|
|
150
|
-
audioFile.dispose();
|
|
151
|
-
}
|
|
152
132
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
133
|
/**
|
|
156
134
|
* Update metadata tags in an audio file and save to disk
|
|
157
135
|
*
|
|
@@ -177,22 +155,15 @@ export async function applyTags(
|
|
|
177
155
|
*
|
|
178
156
|
* @see applyTags - For getting a modified buffer without writing to disk
|
|
179
157
|
*/
|
|
180
|
-
export async function updateTags(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// Get the modified buffer
|
|
190
|
-
const modifiedBuffer = await applyTags(file, tags, options);
|
|
191
|
-
|
|
192
|
-
// Write the buffer back to the file
|
|
193
|
-
await writeFileData(file, modifiedBuffer);
|
|
158
|
+
export async function updateTags(file, tags, options) {
|
|
159
|
+
if (typeof file !== "string") {
|
|
160
|
+
throw new Error("updateTags requires a file path string to save changes");
|
|
161
|
+
}
|
|
162
|
+
// Get the modified buffer
|
|
163
|
+
const modifiedBuffer = await applyTags(file, tags, options);
|
|
164
|
+
// Write the buffer back to the file
|
|
165
|
+
await writeFileData(file, modifiedBuffer);
|
|
194
166
|
}
|
|
195
|
-
|
|
196
167
|
/**
|
|
197
168
|
* Read audio properties from a file
|
|
198
169
|
*
|
|
@@ -207,32 +178,23 @@ export async function updateTags(
|
|
|
207
178
|
* console.log(`Sample rate: ${props.sampleRate} Hz`);
|
|
208
179
|
* ```
|
|
209
180
|
*/
|
|
210
|
-
export async function readProperties(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
181
|
+
export async function readProperties(file) {
|
|
182
|
+
const taglib = await getTagLib();
|
|
183
|
+
const audioFile = await taglib.open(file);
|
|
184
|
+
try {
|
|
185
|
+
if (!audioFile.isValid()) {
|
|
186
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
187
|
+
}
|
|
188
|
+
const props = audioFile.audioProperties();
|
|
189
|
+
if (!props) {
|
|
190
|
+
throw new MetadataError("read", "File may not contain valid audio data", "audioProperties");
|
|
191
|
+
}
|
|
192
|
+
return props;
|
|
220
193
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (!props) {
|
|
224
|
-
throw new MetadataError(
|
|
225
|
-
"read",
|
|
226
|
-
"File may not contain valid audio data",
|
|
227
|
-
"audioProperties",
|
|
228
|
-
);
|
|
194
|
+
finally {
|
|
195
|
+
audioFile.dispose();
|
|
229
196
|
}
|
|
230
|
-
return props;
|
|
231
|
-
} finally {
|
|
232
|
-
audioFile.dispose();
|
|
233
|
-
}
|
|
234
197
|
}
|
|
235
|
-
|
|
236
198
|
/**
|
|
237
199
|
* Tag field constants for go-taglib compatibility.
|
|
238
200
|
* These match the constants used in go-taglib for consistent API.
|
|
@@ -256,9 +218,7 @@ export const Track = "track";
|
|
|
256
218
|
export const AlbumArtist = "albumartist";
|
|
257
219
|
export const Composer = "composer";
|
|
258
220
|
export const DiscNumber = "discnumber";
|
|
259
|
-
|
|
260
221
|
// Additional convenience functions
|
|
261
|
-
|
|
262
222
|
/**
|
|
263
223
|
* Check if a file is a valid audio file
|
|
264
224
|
*
|
|
@@ -272,21 +232,18 @@ export const DiscNumber = "discnumber";
|
|
|
272
232
|
* }
|
|
273
233
|
* ```
|
|
274
234
|
*/
|
|
275
|
-
export async function isValidAudioFile(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return false;
|
|
287
|
-
}
|
|
235
|
+
export async function isValidAudioFile(file) {
|
|
236
|
+
try {
|
|
237
|
+
const taglib = await getTagLib();
|
|
238
|
+
const audioFile = await taglib.open(file);
|
|
239
|
+
const valid = audioFile.isValid();
|
|
240
|
+
audioFile.dispose();
|
|
241
|
+
return valid;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
288
246
|
}
|
|
289
|
-
|
|
290
247
|
/**
|
|
291
248
|
* Get the audio format of a file
|
|
292
249
|
*
|
|
@@ -299,22 +256,19 @@ export async function isValidAudioFile(
|
|
|
299
256
|
* console.log(`File format: ${format}`); // "MP3"
|
|
300
257
|
* ```
|
|
301
258
|
*/
|
|
302
|
-
export async function getFormat(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
259
|
+
export async function getFormat(file) {
|
|
260
|
+
const taglib = await getTagLib();
|
|
261
|
+
const audioFile = await taglib.open(file);
|
|
262
|
+
try {
|
|
263
|
+
if (!audioFile.isValid()) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
return audioFile.getFormat();
|
|
267
|
+
}
|
|
268
|
+
finally {
|
|
269
|
+
audioFile.dispose();
|
|
310
270
|
}
|
|
311
|
-
|
|
312
|
-
return audioFile.getFormat();
|
|
313
|
-
} finally {
|
|
314
|
-
audioFile.dispose();
|
|
315
|
-
}
|
|
316
271
|
}
|
|
317
|
-
|
|
318
272
|
/**
|
|
319
273
|
* Clear all tags from a file
|
|
320
274
|
*
|
|
@@ -327,20 +281,17 @@ export async function getFormat(
|
|
|
327
281
|
* // Save cleanBuffer to remove all metadata
|
|
328
282
|
* ```
|
|
329
283
|
*/
|
|
330
|
-
export async function clearTags(
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
track: 0,
|
|
341
|
-
});
|
|
284
|
+
export async function clearTags(file) {
|
|
285
|
+
return applyTags(file, {
|
|
286
|
+
title: "",
|
|
287
|
+
artist: "",
|
|
288
|
+
album: "",
|
|
289
|
+
comment: "",
|
|
290
|
+
genre: "",
|
|
291
|
+
year: 0,
|
|
292
|
+
track: 0,
|
|
293
|
+
});
|
|
342
294
|
}
|
|
343
|
-
|
|
344
295
|
/**
|
|
345
296
|
* Read cover art/pictures from an audio file
|
|
346
297
|
*
|
|
@@ -355,24 +306,19 @@ export async function clearTags(
|
|
|
355
306
|
* }
|
|
356
307
|
* ```
|
|
357
308
|
*/
|
|
358
|
-
export async function readPictures(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
309
|
+
export async function readPictures(file) {
|
|
310
|
+
const taglib = await getTagLib();
|
|
311
|
+
const audioFile = await taglib.open(file);
|
|
312
|
+
try {
|
|
313
|
+
if (!audioFile.isValid()) {
|
|
314
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
315
|
+
}
|
|
316
|
+
return audioFile.getPictures();
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
audioFile.dispose();
|
|
368
320
|
}
|
|
369
|
-
|
|
370
|
-
return audioFile.getPictures();
|
|
371
|
-
} finally {
|
|
372
|
-
audioFile.dispose();
|
|
373
|
-
}
|
|
374
321
|
}
|
|
375
|
-
|
|
376
322
|
/**
|
|
377
323
|
* Apply pictures/cover art to an audio file and return the modified buffer
|
|
378
324
|
*
|
|
@@ -394,37 +340,26 @@ export async function readPictures(
|
|
|
394
340
|
* const modifiedBuffer = await applyPictures("song.mp3", [coverArt]);
|
|
395
341
|
* ```
|
|
396
342
|
*/
|
|
397
|
-
export async function applyPictures(
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
343
|
+
export async function applyPictures(file, pictures) {
|
|
344
|
+
const taglib = await getTagLib();
|
|
345
|
+
const audioFile = await taglib.open(file);
|
|
346
|
+
try {
|
|
347
|
+
if (!audioFile.isValid()) {
|
|
348
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
349
|
+
}
|
|
350
|
+
// Set the pictures
|
|
351
|
+
audioFile.setPictures(pictures);
|
|
352
|
+
// Save changes to in-memory buffer
|
|
353
|
+
if (!audioFile.save()) {
|
|
354
|
+
throw new FileOperationError("save", "Failed to save picture changes. The file may be read-only or corrupted.");
|
|
355
|
+
}
|
|
356
|
+
// Get the modified buffer after saving
|
|
357
|
+
return audioFile.getFileBuffer();
|
|
408
358
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
audioFile.setPictures(pictures);
|
|
412
|
-
|
|
413
|
-
// Save changes to in-memory buffer
|
|
414
|
-
if (!audioFile.save()) {
|
|
415
|
-
throw new FileOperationError(
|
|
416
|
-
"save",
|
|
417
|
-
"Failed to save picture changes. The file may be read-only or corrupted.",
|
|
418
|
-
);
|
|
359
|
+
finally {
|
|
360
|
+
audioFile.dispose();
|
|
419
361
|
}
|
|
420
|
-
|
|
421
|
-
// Get the modified buffer after saving
|
|
422
|
-
return audioFile.getFileBuffer();
|
|
423
|
-
} finally {
|
|
424
|
-
audioFile.dispose();
|
|
425
|
-
}
|
|
426
362
|
}
|
|
427
|
-
|
|
428
363
|
/**
|
|
429
364
|
* Add a single picture to an audio file and return the modified buffer
|
|
430
365
|
*
|
|
@@ -446,37 +381,26 @@ export async function applyPictures(
|
|
|
446
381
|
* const modifiedBuffer = await addPicture("song.mp3", backCover);
|
|
447
382
|
* ```
|
|
448
383
|
*/
|
|
449
|
-
export async function addPicture(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
384
|
+
export async function addPicture(file, picture) {
|
|
385
|
+
const taglib = await getTagLib();
|
|
386
|
+
const audioFile = await taglib.open(file);
|
|
387
|
+
try {
|
|
388
|
+
if (!audioFile.isValid()) {
|
|
389
|
+
throw new InvalidFormatError("File may be corrupted or in an unsupported format");
|
|
390
|
+
}
|
|
391
|
+
// Add the picture
|
|
392
|
+
audioFile.addPicture(picture);
|
|
393
|
+
// Save changes to in-memory buffer
|
|
394
|
+
if (!audioFile.save()) {
|
|
395
|
+
throw new FileOperationError("save", "Failed to save picture changes. The file may be read-only or corrupted.");
|
|
396
|
+
}
|
|
397
|
+
// Get the modified buffer after saving
|
|
398
|
+
return audioFile.getFileBuffer();
|
|
460
399
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
audioFile.addPicture(picture);
|
|
464
|
-
|
|
465
|
-
// Save changes to in-memory buffer
|
|
466
|
-
if (!audioFile.save()) {
|
|
467
|
-
throw new FileOperationError(
|
|
468
|
-
"save",
|
|
469
|
-
"Failed to save picture changes. The file may be read-only or corrupted.",
|
|
470
|
-
);
|
|
400
|
+
finally {
|
|
401
|
+
audioFile.dispose();
|
|
471
402
|
}
|
|
472
|
-
|
|
473
|
-
// Get the modified buffer after saving
|
|
474
|
-
return audioFile.getFileBuffer();
|
|
475
|
-
} finally {
|
|
476
|
-
audioFile.dispose();
|
|
477
|
-
}
|
|
478
403
|
}
|
|
479
|
-
|
|
480
404
|
/**
|
|
481
405
|
* Clear all pictures from a file
|
|
482
406
|
*
|
|
@@ -489,12 +413,9 @@ export async function addPicture(
|
|
|
489
413
|
* // Save cleanBuffer to remove all cover art
|
|
490
414
|
* ```
|
|
491
415
|
*/
|
|
492
|
-
export async function clearPictures(
|
|
493
|
-
|
|
494
|
-
): Promise<Uint8Array> {
|
|
495
|
-
return applyPictures(file, []);
|
|
416
|
+
export async function clearPictures(file) {
|
|
417
|
+
return applyPictures(file, []);
|
|
496
418
|
}
|
|
497
|
-
|
|
498
419
|
/**
|
|
499
420
|
* Get the primary cover art from an audio file
|
|
500
421
|
*
|
|
@@ -512,26 +433,19 @@ export async function clearPictures(
|
|
|
512
433
|
* }
|
|
513
434
|
* ```
|
|
514
435
|
*/
|
|
515
|
-
export async function getCoverArt(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if (frontCover) {
|
|
528
|
-
return frontCover.data;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// Return first picture if no front cover
|
|
532
|
-
return pictures[0].data;
|
|
436
|
+
export async function getCoverArt(file) {
|
|
437
|
+
const pictures = await readPictures(file);
|
|
438
|
+
if (pictures.length === 0) {
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
// Try to find front cover first
|
|
442
|
+
const frontCover = pictures.find((pic) => pic.type === PictureType.FrontCover);
|
|
443
|
+
if (frontCover) {
|
|
444
|
+
return frontCover.data;
|
|
445
|
+
}
|
|
446
|
+
// Return first picture if no front cover
|
|
447
|
+
return pictures[0].data;
|
|
533
448
|
}
|
|
534
|
-
|
|
535
449
|
/**
|
|
536
450
|
* Set the primary cover art for an audio file
|
|
537
451
|
*
|
|
@@ -548,20 +462,15 @@ export async function getCoverArt(
|
|
|
548
462
|
* const modifiedBuffer = await setCoverArt("song.mp3", jpegData, "image/jpeg");
|
|
549
463
|
* ```
|
|
550
464
|
*/
|
|
551
|
-
export async function setCoverArt(
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
type: PictureType.FrontCover,
|
|
560
|
-
description: "Front Cover",
|
|
561
|
-
};
|
|
562
|
-
return applyPictures(file, [picture]);
|
|
465
|
+
export async function setCoverArt(file, imageData, mimeType) {
|
|
466
|
+
const picture = {
|
|
467
|
+
mimeType,
|
|
468
|
+
data: imageData,
|
|
469
|
+
type: PictureType.FrontCover,
|
|
470
|
+
description: "Front Cover",
|
|
471
|
+
};
|
|
472
|
+
return applyPictures(file, [picture]);
|
|
563
473
|
}
|
|
564
|
-
|
|
565
474
|
/**
|
|
566
475
|
* Find a picture by its type
|
|
567
476
|
*
|
|
@@ -578,13 +487,9 @@ export async function setCoverArt(
|
|
|
578
487
|
* }
|
|
579
488
|
* ```
|
|
580
489
|
*/
|
|
581
|
-
export function findPictureByType(
|
|
582
|
-
|
|
583
|
-
type: PictureType,
|
|
584
|
-
): Picture | null {
|
|
585
|
-
return pictures.find((pic) => pic.type === type) || null;
|
|
490
|
+
export function findPictureByType(pictures, type) {
|
|
491
|
+
return pictures.find((pic) => pic.type === type) || null;
|
|
586
492
|
}
|
|
587
|
-
|
|
588
493
|
/**
|
|
589
494
|
* Replace or add a picture of a specific type
|
|
590
495
|
*
|
|
@@ -606,23 +511,14 @@ export function findPictureByType(
|
|
|
606
511
|
* const modifiedBuffer = await replacePictureByType("song.mp3", backCover);
|
|
607
512
|
* ```
|
|
608
513
|
*/
|
|
609
|
-
export async function replacePictureByType(
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
)
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const filteredPictures = pictures.filter((pic) =>
|
|
617
|
-
pic.type !== newPicture.type
|
|
618
|
-
);
|
|
619
|
-
|
|
620
|
-
// Add the new picture
|
|
621
|
-
filteredPictures.push(newPicture);
|
|
622
|
-
|
|
623
|
-
return applyPictures(file, filteredPictures);
|
|
514
|
+
export async function replacePictureByType(file, newPicture) {
|
|
515
|
+
const pictures = await readPictures(file);
|
|
516
|
+
// Remove any existing picture of the same type
|
|
517
|
+
const filteredPictures = pictures.filter((pic) => pic.type !== newPicture.type);
|
|
518
|
+
// Add the new picture
|
|
519
|
+
filteredPictures.push(newPicture);
|
|
520
|
+
return applyPictures(file, filteredPictures);
|
|
624
521
|
}
|
|
625
|
-
|
|
626
522
|
/**
|
|
627
523
|
* Get picture metadata without the actual image data
|
|
628
524
|
*
|
|
@@ -640,28 +536,14 @@ export async function replacePictureByType(
|
|
|
640
536
|
* }
|
|
641
537
|
* ```
|
|
642
538
|
*/
|
|
643
|
-
export async function getPictureMetadata(
|
|
644
|
-
|
|
645
|
-
)
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}>
|
|
652
|
-
> {
|
|
653
|
-
const pictures = await readPictures(file);
|
|
654
|
-
return pictures.map((pic) => ({
|
|
655
|
-
type: pic.type,
|
|
656
|
-
mimeType: pic.mimeType,
|
|
657
|
-
description: pic.description,
|
|
658
|
-
size: pic.data.length,
|
|
659
|
-
}));
|
|
539
|
+
export async function getPictureMetadata(file) {
|
|
540
|
+
const pictures = await readPictures(file);
|
|
541
|
+
return pictures.map((pic) => ({
|
|
542
|
+
type: pic.type,
|
|
543
|
+
mimeType: pic.mimeType,
|
|
544
|
+
description: pic.description,
|
|
545
|
+
size: pic.data.length,
|
|
546
|
+
}));
|
|
660
547
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
* Re-export commonly used types for convenience.
|
|
664
|
-
* These types define the structure of metadata and audio properties.
|
|
665
|
-
*/
|
|
666
|
-
export type { AudioProperties, Picture, Tag } from "./types.ts";
|
|
667
|
-
export { PictureType } from "./types.ts";
|
|
548
|
+
export { PictureType } from "./types.js";
|
|
549
|
+
//# sourceMappingURL=simple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/simple.ts"],"names":[],"mappings":"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"}
|