taglib-wasm 2.2.2 → 2.3.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/LICENSE +1 -1
- package/README.md +197 -16
- package/dist/index.browser.d.ts +24 -4
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1139 -217
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/simple.browser.js +539 -209
- package/dist/src/constants/properties.d.ts +2 -2
- package/dist/src/constants/specialized-properties.d.ts +2 -2
- package/dist/src/constants/specialized-properties.js +2 -2
- package/dist/src/errors/base.d.ts +17 -2
- package/dist/src/errors/base.d.ts.map +1 -1
- package/dist/src/errors/base.js +18 -0
- package/dist/src/runtime/detector.d.ts +16 -1
- package/dist/src/runtime/detector.d.ts.map +1 -1
- package/dist/src/runtime/detector.js +58 -52
- package/dist/src/runtime/platform-io.d.ts +8 -0
- package/dist/src/runtime/platform-io.d.ts.map +1 -1
- package/dist/src/runtime/platform-io.js +11 -11
- package/dist/src/runtime/unified-loader/module-selection.d.ts +2 -2
- package/dist/src/runtime/unified-loader/module-selection.d.ts.map +1 -1
- package/dist/src/runtime/unified-loader/module-selection.js +3 -5
- package/dist/src/runtime/wasi-adapter/adapter.d.ts +13 -1
- package/dist/src/runtime/wasi-adapter/adapter.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/adapter.js +17 -0
- package/dist/src/runtime/wasi-adapter/audio-properties.d.ts +4 -1
- package/dist/src/runtime/wasi-adapter/audio-properties.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/audio-properties.js +24 -6
- package/dist/src/runtime/wasi-adapter/path-open.d.ts +68 -0
- package/dist/src/runtime/wasi-adapter/path-open.d.ts.map +1 -0
- package/dist/src/runtime/wasi-adapter/path-open.js +76 -0
- package/dist/src/runtime/wasi-adapter/wasm-io.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/wasm-io.js +36 -28
- package/dist/src/runtime/wasi-host-loader.js +8 -3
- package/dist/src/runtime/wasmer-sdk-loader/types.d.ts +13 -0
- package/dist/src/runtime/wasmer-sdk-loader/types.d.ts.map +1 -1
- package/dist/src/simple/checksum-operations.d.ts +25 -0
- package/dist/src/simple/checksum-operations.d.ts.map +1 -0
- package/dist/src/simple/checksum-operations.js +7 -0
- package/dist/src/simple/index.d.ts +2 -0
- package/dist/src/simple/index.d.ts.map +1 -1
- package/dist/src/simple/index.js +2 -0
- package/dist/src/taglib/audio-file-checksum.d.ts +47 -0
- package/dist/src/taglib/audio-file-checksum.d.ts.map +1 -0
- package/dist/src/taglib/audio-file-checksum.js +77 -0
- package/dist/src/taglib/audio-file-impl.d.ts +4 -0
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +34 -2
- package/dist/src/taglib/audio-file-interface.d.ts +17 -0
- package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
- package/dist/src/taglib/embind-adapter.d.ts.map +1 -1
- package/dist/src/taglib/embind-adapter.js +4 -1
- package/dist/src/taglib/id3v2-frames.d.ts.map +1 -1
- package/dist/src/taglib/id3v2-frames.js +2 -2
- package/dist/src/taglib/media-ranges.d.ts +85 -0
- package/dist/src/taglib/media-ranges.d.ts.map +1 -0
- package/dist/src/taglib/media-ranges.js +192 -0
- package/dist/src/taglib/metadata-extent.d.ts +55 -0
- package/dist/src/taglib/metadata-extent.d.ts.map +1 -1
- package/dist/src/taglib/metadata-extent.js +24 -6
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.js +13 -24
- package/dist/src/types/audio-formats.d.ts +5 -5
- package/dist/src/types/audio-formats.d.ts.map +1 -1
- package/dist/src/types/format-property-keys.d.ts +1 -1
- package/dist/src/types/format-property-keys.d.ts.map +1 -1
- package/dist/src/types/tags.d.ts +8 -1
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/utils/path.d.ts +12 -0
- package/dist/src/utils/path.d.ts.map +1 -1
- package/dist/src/utils/path.js +19 -0
- package/dist/src/utils/tag-mapping.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.js +2 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/wasm.d.ts +9 -0
- package/dist/src/wasm.d.ts.map +1 -1
- package/dist/src/web-utils/data-url.d.ts.map +1 -1
- package/dist/src/web-utils/data-url.js +4 -2
- package/dist/taglib-wasi.wasm +0 -0
- package/dist/taglib-web.wasm +0 -0
- package/dist/web.browser.d.ts +13 -0
- package/dist/web.browser.d.ts.map +1 -0
- package/dist/web.browser.js +3630 -0
- package/package.json +19 -17
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileOperationError,
|
|
3
|
+
InvalidFormatError
|
|
4
|
+
} from "../../errors/classes.js";
|
|
5
|
+
import { getFileSize, readPartialFileData } from "../../utils/file.js";
|
|
6
|
+
import { readTagsFromWasm } from "./wasm-io.js";
|
|
7
|
+
const TL_FORMAT_AUTO = 0;
|
|
8
|
+
const HEADER_WINDOW = 4096;
|
|
9
|
+
async function openAudioPath(backend, wasiPath, displayPath) {
|
|
10
|
+
const hostPath = backend.hostModule.hostPathFor(wasiPath);
|
|
11
|
+
if (hostPath === void 0) {
|
|
12
|
+
throw new FileOperationError(
|
|
13
|
+
"read",
|
|
14
|
+
"The path is outside the WASI preopens this host was created with",
|
|
15
|
+
displayPath
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
if (await getFileSize(hostPath) === 0) {
|
|
19
|
+
throw new InvalidFormatError(
|
|
20
|
+
`The file is empty. Path: ${displayPath}`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
const handle = backend.createFileHandle();
|
|
24
|
+
try {
|
|
25
|
+
const loaded = handle.loadFromPath(wasiPath);
|
|
26
|
+
if (!loaded) {
|
|
27
|
+
throw new InvalidFormatError(
|
|
28
|
+
`Failed to load audio file. Path: ${displayPath}`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (!await holdsAudio(backend, wasiPath, handle)) {
|
|
32
|
+
throw new InvalidFormatError(
|
|
33
|
+
`Failed to load audio file. File may be corrupted or in an unsupported format. Path: ${displayPath}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return handle;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
handle.destroy();
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function holdsAudio(backend, wasiPath, handle) {
|
|
43
|
+
return statesAudioProperties(handle) || await hasRecognizableHead(backend, wasiPath);
|
|
44
|
+
}
|
|
45
|
+
function statesAudioProperties(handle) {
|
|
46
|
+
const audio = handle.getAudioProperties();
|
|
47
|
+
return audio !== null && (audio.sampleRate > 0 || audio.channels > 0 || audio.bitrate > 0 || audio.duration > 0 || audio.bitsPerSample > 0);
|
|
48
|
+
}
|
|
49
|
+
async function hasRecognizableHead(backend, wasiPath) {
|
|
50
|
+
const wasi = backend.hostModule;
|
|
51
|
+
const hostPath = wasi.hostPathFor(wasiPath);
|
|
52
|
+
if (hostPath === void 0) return false;
|
|
53
|
+
const head = await readPartialFileData(hostPath, HEADER_WINDOW, 0);
|
|
54
|
+
return detectsFormat(wasi, head) || opensAsBuffer(wasi, head);
|
|
55
|
+
}
|
|
56
|
+
function detectsFormat(wasi, head) {
|
|
57
|
+
const ptr = wasi.malloc(Math.max(head.length, 1));
|
|
58
|
+
try {
|
|
59
|
+
new Uint8Array(wasi.memory.buffer).set(head, ptr);
|
|
60
|
+
return wasi.tl_detect_format(ptr, head.length) !== TL_FORMAT_AUTO;
|
|
61
|
+
} finally {
|
|
62
|
+
wasi.free(ptr);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function opensAsBuffer(wasi, head) {
|
|
66
|
+
try {
|
|
67
|
+
readTagsFromWasm(wasi, head);
|
|
68
|
+
return true;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error instanceof InvalidFormatError) return false;
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
openAudioPath
|
|
76
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-io.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/wasm-io.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"wasm-io.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasi-adapter/wasm-io.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAahE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAyDnD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GACjB,UAAU,CA2BZ;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,GACX,UAAU,CAqBZ;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GAAG,MAAM,EAC3B,EAAE,CAAC,EAAE,MAAM,GACV,aAAa,EAAE,CA0CjB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,OAAO,CA0BT;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,WAAW,GACnB,UAAU,GAAG,IAAI,CA8BnB"}
|
|
@@ -48,13 +48,38 @@ import {
|
|
|
48
48
|
WasmMemoryError
|
|
49
49
|
} from "../wasi-memory.js";
|
|
50
50
|
import {
|
|
51
|
+
FileOperationError,
|
|
51
52
|
InvalidFormatError,
|
|
52
53
|
UnsupportedFormatError
|
|
53
54
|
} from "../../errors/classes.js";
|
|
54
55
|
import { encodeTagData } from "../../msgpack/encoder.js";
|
|
55
56
|
import { decodeMessagePack } from "../../msgpack/decoder.js";
|
|
57
|
+
const TL_ERROR_INVALID_INPUT = -1;
|
|
56
58
|
const TL_ERROR_UNSUPPORTED_FORMAT = -2;
|
|
59
|
+
const TL_ERROR_MEMORY_ALLOCATION = -3;
|
|
60
|
+
const TL_ERROR_IO_READ = -4;
|
|
61
|
+
const TL_ERROR_IO_WRITE = -5;
|
|
57
62
|
const TL_ERROR_PARSE_FAILED = -6;
|
|
63
|
+
function throwForErrorCode(errorCode, operation, where, bufferSize) {
|
|
64
|
+
switch (errorCode) {
|
|
65
|
+
case TL_ERROR_INVALID_INPUT:
|
|
66
|
+
case TL_ERROR_UNSUPPORTED_FORMAT:
|
|
67
|
+
case TL_ERROR_IO_READ:
|
|
68
|
+
case TL_ERROR_PARSE_FAILED:
|
|
69
|
+
throw new InvalidFormatError(
|
|
70
|
+
`File may be corrupted or in an unsupported format${where}`,
|
|
71
|
+
bufferSize
|
|
72
|
+
);
|
|
73
|
+
case TL_ERROR_IO_WRITE:
|
|
74
|
+
throw new FileOperationError("write", `Failed to write tags${where}`);
|
|
75
|
+
default:
|
|
76
|
+
throw new WasmMemoryError(
|
|
77
|
+
`error code ${errorCode}${where}`,
|
|
78
|
+
operation,
|
|
79
|
+
errorCode
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
58
83
|
function readTagsFromWasm(wasi, buffer) {
|
|
59
84
|
var _stack = [];
|
|
60
85
|
try {
|
|
@@ -68,17 +93,11 @@ function readTagsFromWasm(wasi, buffer) {
|
|
|
68
93
|
outSizePtr.ptr
|
|
69
94
|
);
|
|
70
95
|
if (resultPtr === 0) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
throw new InvalidFormatError(
|
|
74
|
-
"File may be corrupted or in an unsupported format",
|
|
75
|
-
buffer.length
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
throw new WasmMemoryError(
|
|
79
|
-
`error code ${errorCode}. Buffer size: ${buffer.length} bytes`,
|
|
96
|
+
throwForErrorCode(
|
|
97
|
+
wasi.tl_get_last_error_code(),
|
|
80
98
|
"read tags",
|
|
81
|
-
|
|
99
|
+
`. Buffer size: ${buffer.length} bytes`,
|
|
100
|
+
buffer.length
|
|
82
101
|
);
|
|
83
102
|
}
|
|
84
103
|
const outSize = outSizePtr.readUint32();
|
|
@@ -100,16 +119,10 @@ function readTagsFromWasmPath(wasi, path) {
|
|
|
100
119
|
const outSizePtr = arena.allocUint32();
|
|
101
120
|
const resultPtr = wasi.tl_read_tags(pathAlloc.ptr, 0, 0, outSizePtr.ptr);
|
|
102
121
|
if (resultPtr === 0) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
throw new InvalidFormatError(
|
|
106
|
-
`File may be corrupted or in an unsupported format. Path: ${path}`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
throw new WasmMemoryError(
|
|
110
|
-
`error code ${errorCode}. Path: ${path}`,
|
|
122
|
+
throwForErrorCode(
|
|
123
|
+
wasi.tl_get_last_error_code(),
|
|
111
124
|
"read tags from path",
|
|
112
|
-
|
|
125
|
+
`. Path: ${path}`
|
|
113
126
|
);
|
|
114
127
|
}
|
|
115
128
|
const outSize = outSizePtr.readUint32();
|
|
@@ -156,11 +169,7 @@ function readId3v2FramesFromWasm(wasi, source, id) {
|
|
|
156
169
|
operation: "readId3v2Frames"
|
|
157
170
|
});
|
|
158
171
|
}
|
|
159
|
-
|
|
160
|
-
`error code ${errorCode}`,
|
|
161
|
-
"read ID3v2 frames",
|
|
162
|
-
errorCode
|
|
163
|
-
);
|
|
172
|
+
throwForErrorCode(errorCode, "read ID3v2 frames", "");
|
|
164
173
|
}
|
|
165
174
|
const outSize = outSizePtr.readUint32();
|
|
166
175
|
const u8 = new Uint8Array(wasi.memory.buffer);
|
|
@@ -191,11 +200,10 @@ function writeTagsToWasmPath(wasi, path, tagData) {
|
|
|
191
200
|
outSizePtr.ptr
|
|
192
201
|
);
|
|
193
202
|
if (result !== 0) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
`error code ${errorCode}. Path: ${path}`,
|
|
203
|
+
throwForErrorCode(
|
|
204
|
+
wasi.tl_get_last_error_code(),
|
|
197
205
|
"write tags to path",
|
|
198
|
-
|
|
206
|
+
`. Path: ${path}`
|
|
199
207
|
);
|
|
200
208
|
}
|
|
201
209
|
return true;
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createWasiImports
|
|
3
3
|
} from "./wasi-host.js";
|
|
4
4
|
import { TagLibError } from "../errors/base.js";
|
|
5
|
-
import { fileUrlToPath } from "../utils/path.js";
|
|
5
|
+
import { fileUrlToPath, hostPathForPreopens } from "../utils/path.js";
|
|
6
6
|
import { isDeno } from "./detector.js";
|
|
7
7
|
class WasiHostLoadError extends TagLibError {
|
|
8
8
|
constructor(message, cause) {
|
|
@@ -55,7 +55,7 @@ async function loadWasiHost(config) {
|
|
|
55
55
|
if (instance.exports._initialize) {
|
|
56
56
|
instance.exports._initialize();
|
|
57
57
|
}
|
|
58
|
-
return createWasiModuleFromInstance(instance, memory, wasiImports);
|
|
58
|
+
return createWasiModuleFromInstance(instance, memory, wasiImports, preopens);
|
|
59
59
|
}
|
|
60
60
|
async function loadWasmBinary(path, fs) {
|
|
61
61
|
if (path.startsWith("http://") || path.startsWith("https://")) {
|
|
@@ -76,7 +76,7 @@ async function loadWasmBinary(path, fs) {
|
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
function createWasiModuleFromInstance(instance, memory, wasiImports) {
|
|
79
|
+
function createWasiModuleFromInstance(instance, memory, wasiImports, preopens) {
|
|
80
80
|
const exports = instance.exports;
|
|
81
81
|
function readCString(ptr) {
|
|
82
82
|
if (!ptr) return "";
|
|
@@ -96,6 +96,11 @@ function createWasiModuleFromInstance(instance, memory, wasiImports) {
|
|
|
96
96
|
tl_read_tags: (pathPtr, bufPtr, len, outSizePtr) => exports.tl_read_tags(pathPtr, bufPtr, len, outSizePtr),
|
|
97
97
|
tl_read_id3v2_frames: (pathPtr, bufPtr, len, idPtr, outSizePtr) => exports.tl_read_id3v2_frames(pathPtr, bufPtr, len, idPtr, outSizePtr),
|
|
98
98
|
tl_write_tags: (pathPtr, bufPtr, len, tagsPtr, tagsSz, outPtr, outSzPtr) => exports.tl_write_tags(pathPtr, bufPtr, len, tagsPtr, tagsSz, outPtr, outSzPtr),
|
|
99
|
+
tl_detect_format: (bufPtr, len) => exports.tl_detect_format(
|
|
100
|
+
bufPtr,
|
|
101
|
+
len
|
|
102
|
+
),
|
|
103
|
+
hostPathFor: (wasiPath) => hostPathForPreopens(wasiPath, preopens),
|
|
99
104
|
tl_get_last_error: () => exports.tl_get_last_error(),
|
|
100
105
|
tl_get_last_error_code: () => exports.tl_get_last_error_code(),
|
|
101
106
|
tl_clear_error: () => exports.tl_clear_error(),
|
|
@@ -16,6 +16,19 @@ export interface WasiModule {
|
|
|
16
16
|
tl_read_tags(pathPtr: number, bufPtr: number, len: number, outSizePtr: number): number;
|
|
17
17
|
tl_read_id3v2_frames(pathPtr: number, bufPtr: number, len: number, idPtr: number, outSizePtr: number): number;
|
|
18
18
|
tl_write_tags(pathPtr: number, bufPtr: number, len: number, tagsPtr: number, tagsSize: number, outBufPtr: number, outSizePtr: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* The boundary's content detector (`src/capi/taglib_boundary.c`), the one the
|
|
21
|
+
* buffer open runs before it picks a file class: a `tl_format` value, or
|
|
22
|
+
* `TL_FORMAT_AUTO` (0) when the bytes are not a container it knows.
|
|
23
|
+
*/
|
|
24
|
+
tl_detect_format(bufPtr: number, len: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* The host path behind a WASI path, resolved through the preopens this host
|
|
27
|
+
* was created with, or undefined when no preopen covers it. Host-side code
|
|
28
|
+
* cannot otherwise read a file the guest reads (`utils/path.ts` carries the
|
|
29
|
+
* rule); the path content gate is the only caller.
|
|
30
|
+
*/
|
|
31
|
+
hostPathFor(wasiPath: string): string | undefined;
|
|
19
32
|
tl_get_last_error(): number;
|
|
20
33
|
tl_get_last_error_code(): number;
|
|
21
34
|
tl_clear_error(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasmer-sdk-loader/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,qBAAa,oBAAqB,SAAQ,WAAW;gBACvC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM7C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAEzB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IAGzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAGxB,YAAY,CACV,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;IACV,oBAAoB,CAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;IACV,aAAa,CACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/runtime/wasmer-sdk-loader/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,qBAAa,oBAAqB,SAAQ,WAAW;gBACvC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM7C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAEzB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IAGzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAGxB,YAAY,CACV,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;IACV,oBAAoB,CAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;IACV,aAAa,CACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC;IAEV;;;;OAIG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtD;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAGlD,iBAAiB,IAAI,MAAM,CAAC;IAC5B,sBAAsB,IAAI,MAAM,CAAC;IACjC,cAAc,IAAI,IAAI,CAAC;IAGvB,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;CAC5B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AudioFileInput } from "../types.js";
|
|
2
|
+
import type { MediaChecksum, MediaChecksumOptions } from "../taglib/audio-file-checksum.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reads a checksum of an audio file's media content.
|
|
5
|
+
*
|
|
6
|
+
* The digest is of the *encoded media payload* — the bytes that are the audio,
|
|
7
|
+
* not the tags around them — so it survives a tag edit, with one boundary: an
|
|
8
|
+
* ID3v2 tag appended after a FLAC's audio is inside that payload, so editing it
|
|
9
|
+
* does move the hash. Formats whose payload cannot be delimited answer the
|
|
10
|
+
* whole file instead and say so (`source: "file"`), where a tag edit does move
|
|
11
|
+
* the hash.
|
|
12
|
+
*
|
|
13
|
+
* @param file - File path, Uint8Array, ArrayBuffer, or File object
|
|
14
|
+
* @param options - `basis: "pcm"` asks for FLAC's STREAMINFO MD5, the digest of
|
|
15
|
+
* the *uncompressed* stream, instead of the encoded payload's SHA-256
|
|
16
|
+
* @returns The hex digest, the algorithm, what it covers (`source`), and how
|
|
17
|
+
* many bytes were hashed
|
|
18
|
+
* @throws {TagLibInitializationError} If the Wasm module fails to initialize
|
|
19
|
+
* @throws {InvalidFormatError} If the file is corrupted or in an unsupported format
|
|
20
|
+
* @throws {UnsupportedFormatError} If `basis: "pcm"` is asked of a non-FLAC file
|
|
21
|
+
* @throws {MetadataError} If the payload cannot be walked, or the handle holds
|
|
22
|
+
* no bytes and no readable source
|
|
23
|
+
*/
|
|
24
|
+
export declare function readMediaChecksum(file: AudioFileInput, options?: MediaChecksumOptions): Promise<MediaChecksum>;
|
|
25
|
+
//# sourceMappingURL=checksum-operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum-operations.d.ts","sourceRoot":"","sources":["../../../src/simple/checksum-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACrB,MAAM,kCAAkC,CAAC;AAG1C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,aAAa,CAAC,CAExB"}
|
|
@@ -3,6 +3,8 @@ export { applyTags, applyTagsToFile, clearTags, isValidAudioFile, readFormat, re
|
|
|
3
3
|
export { addPicture, applyCoverArt, applyPictures, clearPictures, findPictureByType, readCoverArt, readPictureMetadata, readPictures, replacePictureByType, } from "./picture-operations.js";
|
|
4
4
|
export { editTagsBatch, readMetadata, readMetadataBatch, readPropertiesBatch, readTagsBatch, writeTagsBatch, } from "./batch-operations.js";
|
|
5
5
|
export type { BatchItem, BatchOptions, BatchResult, FileMetadata, WriteTagUpdate, } from "./batch-operations.js";
|
|
6
|
+
export { readMediaChecksum } from "./checksum-operations.js";
|
|
7
|
+
export type { ChecksumAlgorithm, ChecksumSource, MediaChecksum, MediaChecksumOptions, } from "../taglib/audio-file-checksum.js";
|
|
6
8
|
export type { AudioProperties, ExtendedTag, Picture, PictureType, Tag, TagInput, } from "../types.js";
|
|
7
9
|
export { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,GAAG,EACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/simple/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,oBAAoB,GACrB,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACX,GAAG,EACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/src/simple/index.js
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
readTagsBatch,
|
|
28
28
|
writeTagsBatch
|
|
29
29
|
} from "./batch-operations.js";
|
|
30
|
+
import { readMediaChecksum } from "./checksum-operations.js";
|
|
30
31
|
import { PICTURE_TYPE_NAMES, PICTURE_TYPE_VALUES } from "../types.js";
|
|
31
32
|
export {
|
|
32
33
|
PICTURE_TYPE_NAMES,
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
isValidAudioFile,
|
|
45
46
|
readCoverArt,
|
|
46
47
|
readFormat,
|
|
48
|
+
readMediaChecksum,
|
|
47
49
|
readMetadata,
|
|
48
50
|
readMetadataBatch,
|
|
49
51
|
readPictureMetadata,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `mediaChecksum()`: a SHA-256 of a file's *encoded media
|
|
3
|
+
* payload* — the bytes that are the audio, and not the tags around them — plus
|
|
4
|
+
* FLAC's STREAMINFO digest passthrough. Factored out of `AudioFileImpl` so the
|
|
5
|
+
* source rule below (what actually gets hashed) is stated exactly once.
|
|
6
|
+
*/
|
|
7
|
+
import type { PlatformIO } from "../runtime/platform-io.js";
|
|
8
|
+
export type MediaChecksum = {
|
|
9
|
+
source: "audio-payload" | "file";
|
|
10
|
+
algorithm: "sha256";
|
|
11
|
+
hex: string;
|
|
12
|
+
bytesHashed: number;
|
|
13
|
+
} | {
|
|
14
|
+
source: "flac-streaminfo-md5";
|
|
15
|
+
algorithm: "md5";
|
|
16
|
+
hex: string;
|
|
17
|
+
bytesHashed: 16;
|
|
18
|
+
};
|
|
19
|
+
export interface MediaChecksumOptions {
|
|
20
|
+
basis?: "encoded" | "pcm";
|
|
21
|
+
}
|
|
22
|
+
/** The literal a checksum's `source` field carries, so a consumer can hold one
|
|
23
|
+
* without restating the values. */
|
|
24
|
+
export type ChecksumSource = MediaChecksum["source"];
|
|
25
|
+
/** The algorithm any returned checksum can carry — narrowed by `source`. */
|
|
26
|
+
export type ChecksumAlgorithm = MediaChecksum["algorithm"];
|
|
27
|
+
/**
|
|
28
|
+
* What the checksum needs from the open handle — module-internal, and not
|
|
29
|
+
* re-exported from either entry point (`ChecksumSource` above is the public name,
|
|
30
|
+
* and a handle descriptor must not shadow it).
|
|
31
|
+
*/
|
|
32
|
+
interface ChecksumHandleSource {
|
|
33
|
+
/** The bytes the handle holds — a full file, a partial-load window image, or
|
|
34
|
+
* nothing at all when the data lives on disk (WASI path mode). */
|
|
35
|
+
bytes: Uint8Array;
|
|
36
|
+
/** The path, when the handle was opened from one. */
|
|
37
|
+
path?: string;
|
|
38
|
+
/** The File/Blob, when the handle was opened from one. */
|
|
39
|
+
blob?: Blob;
|
|
40
|
+
/** True when `bytes` is a spliced header+footer image rather than the file.
|
|
41
|
+
* Must be captured when the handle is created: `saveToFile()` clears the
|
|
42
|
+
* instance's own flag while the bytes stay spliced. */
|
|
43
|
+
partiallyLoaded: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare function mediaChecksum(source: ChecksumHandleSource, format: string, io: PlatformIO, options?: MediaChecksumOptions): Promise<MediaChecksum>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=audio-file-checksum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-file-checksum.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-checksum.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG5D,MAAM,MAAM,aAAa,GACrB;IACA,MAAM,EAAE,eAAe,GAAG,MAAM,CAAC;IACjC,SAAS,EAAE,QAAQ,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB,GACC;IACA,MAAM,EAAE,qBAAqB,CAAC;IAC9B,SAAS,EAAE,KAAK,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,EAAE,CAAC;CACjB,CAAC;AAEJ,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;CAC3B;AAED;mCACmC;AACnC,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;AAErD,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;AAE3D;;;;GAIG;AACH,UAAU,oBAAoB;IAC5B;sEACkE;IAClE,KAAK,EAAE,UAAU,CAAC;IAClB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;2DAEuD;IACvD,eAAe,EAAE,OAAO,CAAC;CAC1B;AA6FD,wBAAsB,aAAa,CACjC,MAAM,EAAE,oBAAoB,EAC5B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,UAAU,EACd,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CAoExB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { flacStreamInfoMd5, mediaRanges } from "./media-ranges.js";
|
|
2
|
+
import { MetadataError, UnsupportedFormatError } from "../errors.js";
|
|
3
|
+
const STREAMINFO_WINDOW = 65536;
|
|
4
|
+
async function fileBytes(source, io) {
|
|
5
|
+
if (source.path) return await io.readFile(source.path);
|
|
6
|
+
if (source.blob) return new Uint8Array(await source.blob.arrayBuffer());
|
|
7
|
+
if (!source.partiallyLoaded && source.bytes.length > 0) return source.bytes;
|
|
8
|
+
throw new MetadataError(
|
|
9
|
+
"read",
|
|
10
|
+
"the handle holds no file bytes and has no readable source; a partial handle that has been saved drops its source \u2014 checksum the saved path instead"
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
function joinRanges(bytes, ranges) {
|
|
14
|
+
const total = ranges.reduce((n, r) => n + r.length, 0);
|
|
15
|
+
const overrun = ranges.find((r) => r.offset + r.length > bytes.length);
|
|
16
|
+
if (overrun || total > bytes.length) {
|
|
17
|
+
throw new MetadataError(
|
|
18
|
+
"read",
|
|
19
|
+
`range walk overran the buffer (${overrun ? `range ${overrun.offset}+${overrun.length}` : `${total} bytes`} past the ${bytes.length}-byte buffer)`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (ranges.length === 1) {
|
|
23
|
+
const only = ranges[0];
|
|
24
|
+
const view = bytes.subarray(only.offset, only.offset + only.length);
|
|
25
|
+
return view.buffer instanceof ArrayBuffer ? view : new Uint8Array(view);
|
|
26
|
+
}
|
|
27
|
+
const out = new Uint8Array(total);
|
|
28
|
+
let at = 0;
|
|
29
|
+
for (const r of ranges) {
|
|
30
|
+
out.set(bytes.subarray(r.offset, r.offset + r.length), at);
|
|
31
|
+
at += r.length;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
async function mediaChecksum(source, format, io, options = {}) {
|
|
36
|
+
if (options.basis === "pcm") {
|
|
37
|
+
if (format.toUpperCase() !== "FLAC") {
|
|
38
|
+
throw new UnsupportedFormatError(format, ["FLAC"], {
|
|
39
|
+
operation: "media checksum (basis: pcm)"
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const windowed = source.bytes.length > 0 ? source.bytes : source.path && io.readPartial ? await io.readPartial(source.path, STREAMINFO_WINDOW, 0) : void 0;
|
|
43
|
+
let md5 = windowed === void 0 ? void 0 : flacStreamInfoMd5(windowed);
|
|
44
|
+
if (md5 === void 0 && windowed !== source.bytes) {
|
|
45
|
+
md5 = flacStreamInfoMd5(await fileBytes(source, io));
|
|
46
|
+
}
|
|
47
|
+
if (md5 === void 0) {
|
|
48
|
+
throw new MetadataError(
|
|
49
|
+
"read",
|
|
50
|
+
"STREAMINFO digest unavailable"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
source: "flac-streaminfo-md5",
|
|
55
|
+
algorithm: "md5",
|
|
56
|
+
hex: md5,
|
|
57
|
+
bytesHashed: 16
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const bytes = await fileBytes(source, io);
|
|
61
|
+
const walk = mediaRanges(format, bytes);
|
|
62
|
+
const payload = joinRanges(bytes, walk.ranges);
|
|
63
|
+
const digest = new Uint8Array(
|
|
64
|
+
await crypto.subtle.digest("SHA-256", payload)
|
|
65
|
+
);
|
|
66
|
+
let hex = "";
|
|
67
|
+
for (const byte of digest) hex += byte.toString(16).padStart(2, "0");
|
|
68
|
+
return {
|
|
69
|
+
source: walk.kind === "ranges" ? "audio-payload" : "file",
|
|
70
|
+
algorithm: "sha256",
|
|
71
|
+
hex,
|
|
72
|
+
bytesHashed: payload.length
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
mediaChecksum
|
|
77
|
+
};
|
|
@@ -6,6 +6,7 @@ import type { Id3v2Frame, Rating, UnsyncedLyrics } from "../constants/complex-pr
|
|
|
6
6
|
import { type NormalizedRating } from "../utils/rating.js";
|
|
7
7
|
import type { AudioFile } from "./audio-file-interface.js";
|
|
8
8
|
import { BaseAudioFileImpl } from "./audio-file-base.js";
|
|
9
|
+
import { type MediaChecksum, type MediaChecksumOptions } from "./audio-file-checksum.js";
|
|
9
10
|
/** @internal Exported for unit tests (tests/node-fs-acquisition.test.ts). */
|
|
10
11
|
export declare function readFileSync(path: string): Uint8Array;
|
|
11
12
|
/**
|
|
@@ -16,9 +17,12 @@ export declare function readFileSync(path: string): Uint8Array;
|
|
|
16
17
|
*/
|
|
17
18
|
export declare class AudioFileImpl extends BaseAudioFileImpl implements AudioFile {
|
|
18
19
|
private pathModeBuffer;
|
|
20
|
+
/** How the handle was loaded — `isPartiallyLoaded` is mutated by saveToFile(). */
|
|
21
|
+
private readonly partiallyLoadedAtConstruction;
|
|
19
22
|
constructor(module: TagLibModule, fileHandle: WasmFileHandle, sourcePath?: string, originalSource?: string | Uint8Array | ArrayBuffer | File, isPartiallyLoaded?: boolean, partialLoadOptions?: OpenOptions);
|
|
20
23
|
save(): boolean;
|
|
21
24
|
getFileBuffer(): Uint8Array;
|
|
25
|
+
mediaChecksum(options?: MediaChecksumOptions): Promise<MediaChecksum>;
|
|
22
26
|
saveToFile(path?: string): Promise<void>;
|
|
23
27
|
getPictures(): Picture[];
|
|
24
28
|
setPictures(pictures: Picture[]): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,KAAK,EACV,UAAU,EACV,MAAM,EACN,cAAc,EACf,MAAM,oCAAoC,CAAC;AAc5C,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"audio-file-impl.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,10 @@ import { getNodeFsSync } from "../utils/node-fs.js";
|
|
|
19
19
|
import { normalized } from "../utils/rating.js";
|
|
20
20
|
import { isDeno } from "../runtime/detector.js";
|
|
21
21
|
import { BaseAudioFileImpl } from "./audio-file-base.js";
|
|
22
|
+
import {
|
|
23
|
+
mediaChecksum
|
|
24
|
+
} from "./audio-file-checksum.js";
|
|
25
|
+
import { getPlatformIO } from "../runtime/platform-io.js";
|
|
22
26
|
import { saveViaFreshHandle } from "./save-reconstruct.js";
|
|
23
27
|
function sortChapters(list) {
|
|
24
28
|
return [...list].sort((a, b) => a.startTimeMs - b.startTimeMs);
|
|
@@ -50,6 +54,9 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
50
54
|
partialLoadOptions
|
|
51
55
|
);
|
|
52
56
|
__publicField(this, "pathModeBuffer", null);
|
|
57
|
+
/** How the handle was loaded — `isPartiallyLoaded` is mutated by saveToFile(). */
|
|
58
|
+
__publicField(this, "partiallyLoadedAtConstruction");
|
|
59
|
+
this.partiallyLoadedAtConstruction = isPartiallyLoaded;
|
|
53
60
|
}
|
|
54
61
|
save() {
|
|
55
62
|
if (this.isPartiallyLoaded && this.originalSource) {
|
|
@@ -85,6 +92,31 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
85
92
|
"No file data available: in-memory buffer is empty and no source path is set"
|
|
86
93
|
);
|
|
87
94
|
}
|
|
95
|
+
mediaChecksum(options) {
|
|
96
|
+
return mediaChecksum(
|
|
97
|
+
{
|
|
98
|
+
// The cheap, no-IO accessor — `getFileBuffer()` would read the whole
|
|
99
|
+
// file from disk in path mode (and cache it), which the source rule is
|
|
100
|
+
// about to read for itself.
|
|
101
|
+
bytes: this.handle.getBuffer(),
|
|
102
|
+
// empty in path mode: the data is on disk
|
|
103
|
+
// Both optional fields are conditional: they are `undefined` far more
|
|
104
|
+
// often than not, and `exactOptionalPropertyTypes` refuses an explicit
|
|
105
|
+
// `undefined` on an optional property.
|
|
106
|
+
...this.sourcePath !== void 0 ? { path: this.sourcePath } : {},
|
|
107
|
+
// originalSource is the File when the caller passed one. A partial File
|
|
108
|
+
// has no path, so this is the only way back to the real bytes.
|
|
109
|
+
...this.originalSource instanceof Blob ? { blob: this.originalSource } : {},
|
|
110
|
+
// Captured at construction, NOT this.isPartiallyLoaded: saveToFile() sets
|
|
111
|
+
// that flag false (and clears originalSource) while the handle still holds
|
|
112
|
+
// the spliced image, which would make the source rule hash the image.
|
|
113
|
+
partiallyLoaded: this.partiallyLoadedAtConstruction
|
|
114
|
+
},
|
|
115
|
+
this.getFormat(),
|
|
116
|
+
getPlatformIO(),
|
|
117
|
+
options
|
|
118
|
+
);
|
|
119
|
+
}
|
|
88
120
|
async saveToFile(path) {
|
|
89
121
|
const targetPath = path ?? this.sourcePath;
|
|
90
122
|
if (!targetPath) {
|
|
@@ -174,8 +206,8 @@ class AudioFileImpl extends BaseAudioFileImpl {
|
|
|
174
206
|
}
|
|
175
207
|
setChapters(chapters, options) {
|
|
176
208
|
const fmt = this.getFormat();
|
|
177
|
-
if (fmt !== "MP3" && fmt !== "MP4") {
|
|
178
|
-
throw new UnsupportedFormatError(fmt, ["MP3", "MP4"], {
|
|
209
|
+
if (fmt !== "MP3" && fmt !== "AAC" && fmt !== "MP4") {
|
|
210
|
+
throw new UnsupportedFormatError(fmt, ["MP3", "AAC", "MP4"], {
|
|
179
211
|
operation: "setChapters"
|
|
180
212
|
});
|
|
181
213
|
}
|
|
@@ -2,6 +2,7 @@ import type { AudioProperties, FileType, Picture, PropertyMap } from "../types.j
|
|
|
2
2
|
import type { TypedAudioProperties } from "../types/audio-formats.js";
|
|
3
3
|
import type { Id3v2Frame, Rating, UnsyncedLyrics } from "../constants/complex-properties.js";
|
|
4
4
|
import type { MutableTag } from "./mutable-tag.js";
|
|
5
|
+
import type { MediaChecksum, MediaChecksumOptions } from "./audio-file-checksum.js";
|
|
5
6
|
import type { FormatPropertyKey } from "../types/format-property-keys.js";
|
|
6
7
|
import type { NormalizedRating } from "../utils/rating.js";
|
|
7
8
|
/**
|
|
@@ -66,6 +67,22 @@ export interface AudioFile {
|
|
|
66
67
|
* and cannot be read back — never returns an empty buffer on failure.
|
|
67
68
|
*/
|
|
68
69
|
getFileBuffer(): Uint8Array;
|
|
70
|
+
/**
|
|
71
|
+
* SHA-256 of the file's encoded media payload — the bytes that are the audio,
|
|
72
|
+
* not the tags around them — so the digest survives a tag edit, with one
|
|
73
|
+
* boundary: an ID3v2 tag appended after a FLAC's audio is inside the payload,
|
|
74
|
+
* so editing it does move the hash. Formats whose payload cannot be delimited
|
|
75
|
+
* answer the whole file instead and say so (`source: "file"`), where a tag
|
|
76
|
+
* edit does move the hash.
|
|
77
|
+
*
|
|
78
|
+
* Pass `{ basis: "pcm" }` for FLAC's STREAMINFO MD5 — the digest of the
|
|
79
|
+
* *uncompressed* stream, read straight from the file's first metadata block.
|
|
80
|
+
* Other formats throw {@link UnsupportedFormatError}.
|
|
81
|
+
*
|
|
82
|
+
* @throws {MetadataError} If the handle holds no file bytes and has no
|
|
83
|
+
* readable source (a partial handle that has already been saved).
|
|
84
|
+
*/
|
|
85
|
+
mediaChecksum(options?: MediaChecksumOptions): Promise<MediaChecksum>;
|
|
69
86
|
/**
|
|
70
87
|
* Save all changes to a file on disk.
|
|
71
88
|
* @param path - Optional file path. If not provided, saves to the original path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-file-interface.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-interface.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audio-file-interface.d.ts","sourceRoot":"","sources":["../../../src/taglib/audio-file-interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embind-adapter.d.ts","sourceRoot":"","sources":["../../../src/taglib/embind-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAyB,cAAc,EAAE,MAAM,YAAY,CAAC;AAcxE,wEAAwE;AACxE,UAAU,gBAAgB;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,IAAI,MAAM,CAAC;IACjB,KAAK,IAAI,MAAM,CAAC;IAChB,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oFAAoF;AACpF,UAAU,4BAA4B;IACpC,eAAe,IAAI,MAAM,CAAC;IAC1B,oBAAoB,IAAI,MAAM,CAAC;IAC/B,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,MAAM,CAAC;IACrB,QAAQ,IAAI,MAAM,CAAC;IACnB,aAAa,IAAI,MAAM,CAAC;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,eAAe,IAAI,MAAM,CAAC;IAC1B,UAAU,IAAI,OAAO,CAAC;IACtB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,IAAI,gBAAgB,CAAC;IAC3B,kBAAkB,IAAI,4BAA4B,GAAG,IAAI,CAAC;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"embind-adapter.d.ts","sourceRoot":"","sources":["../../../src/taglib/embind-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAyB,cAAc,EAAE,MAAM,YAAY,CAAC;AAcxE,wEAAwE;AACxE,UAAU,gBAAgB;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,MAAM,IAAI,MAAM,CAAC;IACjB,KAAK,IAAI,MAAM,CAAC;IAChB,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,IAAI,IAAI,MAAM,CAAC;IACf,KAAK,IAAI,MAAM,CAAC;IAChB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oFAAoF;AACpF,UAAU,4BAA4B;IACpC,eAAe,IAAI,MAAM,CAAC;IAC1B,oBAAoB,IAAI,MAAM,CAAC;IAC/B,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,MAAM,CAAC;IACrB,QAAQ,IAAI,MAAM,CAAC;IACnB,aAAa,IAAI,MAAM,CAAC;IACxB,KAAK,IAAI,MAAM,CAAC;IAChB,eAAe,IAAI,MAAM,CAAC;IAC1B,UAAU,IAAI,OAAO,CAAC;IACtB,WAAW,IAAI,MAAM,CAAC;IACtB,SAAS,IAAI,MAAM,CAAC;IACpB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,MAAM,CAAC;IACxB,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,IAAI,gBAAgB,CAAC;IAC3B,kBAAkB,IAAI,4BAA4B,GAAG,IAAI,CAAC;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,cAAc,CAyKtE"}
|
|
@@ -121,7 +121,10 @@ function wrapEmbindHandle(raw) {
|
|
|
121
121
|
...containerFormat === "MP4" || containerFormat === "ASF" ? { isEncrypted: pw.isEncrypted() } : {},
|
|
122
122
|
...formatVersion > 0 ? { formatVersion } : {},
|
|
123
123
|
...isValidBitrateMode(bitrateMode) ? { bitrateMode } : {},
|
|
124
|
-
|
|
124
|
+
// OpusHead gain exists only in an Ogg Opus stream. Gating on codec
|
|
125
|
+
// alone fabricated outputGainDb: 0 for MP4 tracks once the MP4 codec
|
|
126
|
+
// enum was mapped (the WASI side never emitted it there) — taglib-kswf.
|
|
127
|
+
...containerFormat === "OGG" && codec === "Opus" ? { outputGainDb: pw.outputGainDb() } : {}
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id3v2-frames.d.ts","sourceRoot":"","sources":["../../../src/taglib/id3v2-frames.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAIrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"id3v2-frames.d.ts","sourceRoot":"","sources":["../../../src/taglib/id3v2-frames.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAIrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ9C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAQ3E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,IAAI,CAUtE;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAM9D"}
|