mediabunny 1.17.3 → 1.18.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/dist/bundles/mediabunny.cjs +179 -30
- package/dist/bundles/mediabunny.min.cjs +4 -4
- package/dist/bundles/mediabunny.min.mjs +4 -4
- package/dist/bundles/mediabunny.mjs +179 -30
- package/dist/mediabunny.d.ts +32 -3
- package/dist/modules/shared/mp3-misc.js +3 -3
- package/dist/modules/src/index.d.ts +1 -1
- package/dist/modules/src/index.d.ts.map +1 -1
- package/dist/modules/src/index.js +1 -1
- package/dist/modules/src/input-format.js +1 -1
- package/dist/modules/src/matroska/ebml.d.ts +4 -1
- package/dist/modules/src/matroska/ebml.d.ts.map +1 -1
- package/dist/modules/src/matroska/ebml.js +49 -0
- package/dist/modules/src/matroska/matroska-demuxer.d.ts +1 -0
- package/dist/modules/src/matroska/matroska-demuxer.d.ts.map +1 -1
- package/dist/modules/src/matroska/matroska-demuxer.js +19 -3
- package/dist/modules/src/matroska/matroska-muxer.d.ts.map +1 -1
- package/dist/modules/src/matroska/matroska-muxer.js +65 -29
- package/dist/modules/src/misc.d.ts +7 -1
- package/dist/modules/src/misc.d.ts.map +1 -1
- package/dist/modules/src/misc.js +51 -13
- package/dist/modules/src/source.js +3 -3
- package/dist/modules/src/tags.d.ts +31 -3
- package/dist/modules/src/tags.d.ts.map +1 -1
- package/dist/modules/src/tags.js +45 -2
- package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/input-format.ts +1 -1
- package/src/matroska/ebml.ts +54 -4
- package/src/matroska/matroska-demuxer.ts +25 -3
- package/src/matroska/matroska-muxer.ts +54 -11
- package/src/misc.ts +65 -18
- package/src/source.ts +3 -3
- package/src/tags.ts +48 -5
|
@@ -53,6 +53,7 @@ var Mediabunny = (() => {
|
|
|
53
53
|
AUDIO_CODECS: () => AUDIO_CODECS,
|
|
54
54
|
AdtsInputFormat: () => AdtsInputFormat,
|
|
55
55
|
AdtsOutputFormat: () => AdtsOutputFormat,
|
|
56
|
+
AttachedFile: () => AttachedFile,
|
|
56
57
|
AudioBufferSink: () => AudioBufferSink,
|
|
57
58
|
AudioBufferSource: () => AudioBufferSource,
|
|
58
59
|
AudioSample: () => AudioSample,
|
|
@@ -526,19 +527,41 @@ var Mediabunny = (() => {
|
|
|
526
527
|
return ISO_639_2_REGEX.test(x);
|
|
527
528
|
};
|
|
528
529
|
var SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);
|
|
529
|
-
var
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
530
|
+
var mergeRequestInit = (init1, init2) => {
|
|
531
|
+
const merged = { ...init1, ...init2 };
|
|
532
|
+
if (init1.headers || init2.headers) {
|
|
533
|
+
const headers1 = init1.headers ? normalizeHeaders(init1.headers) : {};
|
|
534
|
+
const headers2 = init2.headers ? normalizeHeaders(init2.headers) : {};
|
|
535
|
+
const mergedHeaders = { ...headers1 };
|
|
536
|
+
Object.entries(headers2).forEach(([key2, value2]) => {
|
|
537
|
+
const existingKey = Object.keys(mergedHeaders).find(
|
|
538
|
+
(key1) => key1.toLowerCase() === key2.toLowerCase()
|
|
536
539
|
);
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
+
if (existingKey) {
|
|
541
|
+
delete mergedHeaders[existingKey];
|
|
542
|
+
}
|
|
543
|
+
mergedHeaders[key2] = value2;
|
|
544
|
+
});
|
|
545
|
+
merged.headers = mergedHeaders;
|
|
540
546
|
}
|
|
541
|
-
return
|
|
547
|
+
return merged;
|
|
548
|
+
};
|
|
549
|
+
var normalizeHeaders = (headers) => {
|
|
550
|
+
if (headers instanceof Headers) {
|
|
551
|
+
const result = {};
|
|
552
|
+
headers.forEach((value, key) => {
|
|
553
|
+
result[key] = value;
|
|
554
|
+
});
|
|
555
|
+
return result;
|
|
556
|
+
}
|
|
557
|
+
if (Array.isArray(headers)) {
|
|
558
|
+
const result = {};
|
|
559
|
+
headers.forEach(([key, value]) => {
|
|
560
|
+
result[key] = value;
|
|
561
|
+
});
|
|
562
|
+
return result;
|
|
563
|
+
}
|
|
564
|
+
return headers;
|
|
542
565
|
};
|
|
543
566
|
var retriedFetch = async (url2, requestInit, getRetryDelay) => {
|
|
544
567
|
let attempts = 0;
|
|
@@ -671,6 +694,17 @@ var Mediabunny = (() => {
|
|
|
671
694
|
}
|
|
672
695
|
return btoa(string);
|
|
673
696
|
};
|
|
697
|
+
var uint8ArraysAreEqual = (a, b) => {
|
|
698
|
+
if (a.length !== b.length) {
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
for (let i = 0; i < a.length; i++) {
|
|
702
|
+
if (a[i] !== b[i]) {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return true;
|
|
707
|
+
};
|
|
674
708
|
|
|
675
709
|
// src/tags.ts
|
|
676
710
|
var RichImageData = class {
|
|
@@ -678,6 +712,33 @@ var Mediabunny = (() => {
|
|
|
678
712
|
constructor(data, mimeType) {
|
|
679
713
|
this.data = data;
|
|
680
714
|
this.mimeType = mimeType;
|
|
715
|
+
if (!(data instanceof Uint8Array)) {
|
|
716
|
+
throw new TypeError("data must be a Uint8Array.");
|
|
717
|
+
}
|
|
718
|
+
if (typeof mimeType !== "string") {
|
|
719
|
+
throw new TypeError("mimeType must be a string.");
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
var AttachedFile = class {
|
|
724
|
+
/** Creates a new {@link AttachedFile}. */
|
|
725
|
+
constructor(data, mimeType, name, description) {
|
|
726
|
+
this.data = data;
|
|
727
|
+
this.mimeType = mimeType;
|
|
728
|
+
this.name = name;
|
|
729
|
+
this.description = description;
|
|
730
|
+
if (!(data instanceof Uint8Array)) {
|
|
731
|
+
throw new TypeError("data must be a Uint8Array.");
|
|
732
|
+
}
|
|
733
|
+
if (mimeType !== void 0 && typeof mimeType !== "string") {
|
|
734
|
+
throw new TypeError("mimeType, when provided, must be a string.");
|
|
735
|
+
}
|
|
736
|
+
if (name !== void 0 && typeof name !== "string") {
|
|
737
|
+
throw new TypeError("name, when provided, must be a string.");
|
|
738
|
+
}
|
|
739
|
+
if (description !== void 0 && typeof description !== "string") {
|
|
740
|
+
throw new TypeError("description, when provided, must be a string.");
|
|
741
|
+
}
|
|
681
742
|
}
|
|
682
743
|
};
|
|
683
744
|
var validateMetadataTags = (tags) => {
|
|
@@ -747,9 +808,9 @@ var Mediabunny = (() => {
|
|
|
747
808
|
throw new TypeError("tags.raw, when provided, must be an object.");
|
|
748
809
|
}
|
|
749
810
|
for (const value of Object.values(tags.raw)) {
|
|
750
|
-
if (value !== null && typeof value !== "string" && !(value instanceof Uint8Array) && !(value instanceof RichImageData)) {
|
|
811
|
+
if (value !== null && typeof value !== "string" && !(value instanceof Uint8Array) && !(value instanceof RichImageData) && !(value instanceof AttachedFile)) {
|
|
751
812
|
throw new TypeError(
|
|
752
|
-
"Each value in tags.raw must be a string, Uint8Array, RichImageData, or null."
|
|
813
|
+
"Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, or null."
|
|
753
814
|
);
|
|
754
815
|
}
|
|
755
816
|
}
|
|
@@ -6668,6 +6729,25 @@ var Mediabunny = (() => {
|
|
|
6668
6729
|
return 6;
|
|
6669
6730
|
}
|
|
6670
6731
|
};
|
|
6732
|
+
var measureUnsignedBigInt = (value) => {
|
|
6733
|
+
if (value < 1n << 8n) {
|
|
6734
|
+
return 1;
|
|
6735
|
+
} else if (value < 1n << 16n) {
|
|
6736
|
+
return 2;
|
|
6737
|
+
} else if (value < 1n << 24n) {
|
|
6738
|
+
return 3;
|
|
6739
|
+
} else if (value < 1n << 32n) {
|
|
6740
|
+
return 4;
|
|
6741
|
+
} else if (value < 1n << 40n) {
|
|
6742
|
+
return 5;
|
|
6743
|
+
} else if (value < 1n << 48n) {
|
|
6744
|
+
return 6;
|
|
6745
|
+
} else if (value < 1n << 56n) {
|
|
6746
|
+
return 7;
|
|
6747
|
+
} else {
|
|
6748
|
+
return 8;
|
|
6749
|
+
}
|
|
6750
|
+
};
|
|
6671
6751
|
var measureSignedInt = (value) => {
|
|
6672
6752
|
if (value >= -(1 << 6) && value < 1 << 6) {
|
|
6673
6753
|
return 1;
|
|
@@ -6751,6 +6831,13 @@ var Mediabunny = (() => {
|
|
|
6751
6831
|
}
|
|
6752
6832
|
this.writer.write(this.helper.subarray(0, pos));
|
|
6753
6833
|
}
|
|
6834
|
+
writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {
|
|
6835
|
+
let pos = 0;
|
|
6836
|
+
for (let i = width - 1; i >= 0; i--) {
|
|
6837
|
+
this.helperView.setUint8(pos++, Number(value >> BigInt(i * 8) & 0xffn));
|
|
6838
|
+
}
|
|
6839
|
+
this.writer.write(this.helper.subarray(0, pos));
|
|
6840
|
+
}
|
|
6754
6841
|
writeSignedInt(value, width = measureSignedInt(value)) {
|
|
6755
6842
|
if (value < 0) {
|
|
6756
6843
|
value += 2 ** (width * 8);
|
|
@@ -6834,6 +6921,10 @@ var Mediabunny = (() => {
|
|
|
6834
6921
|
const size = data.size ?? measureUnsignedInt(data.data);
|
|
6835
6922
|
this.writeVarInt(size);
|
|
6836
6923
|
this.writeUnsignedInt(data.data, size);
|
|
6924
|
+
} else if (typeof data.data === "bigint") {
|
|
6925
|
+
const size = data.size ?? measureUnsignedBigInt(data.data);
|
|
6926
|
+
this.writeVarInt(size);
|
|
6927
|
+
this.writeUnsignedBigInt(data.data, size);
|
|
6837
6928
|
} else if (typeof data.data === "string") {
|
|
6838
6929
|
this.writeVarInt(data.data.length);
|
|
6839
6930
|
this.writeAsciiString(data.data);
|
|
@@ -6906,6 +6997,17 @@ var Mediabunny = (() => {
|
|
|
6906
6997
|
}
|
|
6907
6998
|
return value;
|
|
6908
6999
|
};
|
|
7000
|
+
var readUnsignedBigInt = (slice, width) => {
|
|
7001
|
+
if (width < 1) {
|
|
7002
|
+
throw new Error("Bad unsigned int size " + width);
|
|
7003
|
+
}
|
|
7004
|
+
let value = 0n;
|
|
7005
|
+
for (let i = 0; i < width; i++) {
|
|
7006
|
+
value <<= 8n;
|
|
7007
|
+
value += BigInt(readU8(slice));
|
|
7008
|
+
}
|
|
7009
|
+
return value;
|
|
7010
|
+
};
|
|
6909
7011
|
var readSignedInt = (slice, width) => {
|
|
6910
7012
|
let value = readUnsignedInt(slice, width);
|
|
6911
7013
|
if (value & 1 << width * 8 - 1) {
|
|
@@ -7418,11 +7520,10 @@ var Mediabunny = (() => {
|
|
|
7418
7520
|
}
|
|
7419
7521
|
maybeCreateAttachments() {
|
|
7420
7522
|
const metadataTags = this.output._metadataTags;
|
|
7421
|
-
|
|
7422
|
-
return;
|
|
7423
|
-
}
|
|
7523
|
+
const elements = [];
|
|
7424
7524
|
const existingFileUids = /* @__PURE__ */ new Set();
|
|
7425
|
-
|
|
7525
|
+
const images = metadataTags.images ?? [];
|
|
7526
|
+
for (const image of images) {
|
|
7426
7527
|
let imageName = image.name;
|
|
7427
7528
|
if (imageName === void 0) {
|
|
7428
7529
|
const baseName = image.kind === "coverFront" ? "cover" : image.kind === "coverBack" ? "back" : "image";
|
|
@@ -7430,13 +7531,17 @@ var Mediabunny = (() => {
|
|
|
7430
7531
|
}
|
|
7431
7532
|
let fileUid;
|
|
7432
7533
|
while (true) {
|
|
7433
|
-
fileUid =
|
|
7434
|
-
|
|
7534
|
+
fileUid = 0n;
|
|
7535
|
+
for (let i = 0; i < 8; i++) {
|
|
7536
|
+
fileUid <<= 8n;
|
|
7537
|
+
fileUid |= BigInt(Math.floor(Math.random() * 256));
|
|
7538
|
+
}
|
|
7539
|
+
if (fileUid !== 0n && !existingFileUids.has(fileUid)) {
|
|
7435
7540
|
break;
|
|
7436
7541
|
}
|
|
7437
7542
|
}
|
|
7438
7543
|
existingFileUids.add(fileUid);
|
|
7439
|
-
|
|
7544
|
+
elements.push({
|
|
7440
7545
|
id: 24999 /* AttachedFile */,
|
|
7441
7546
|
data: [
|
|
7442
7547
|
image.description !== void 0 ? { id: 18046 /* FileDescription */, data: new EBMLUnicodeString(image.description) } : null,
|
|
@@ -7445,8 +7550,34 @@ var Mediabunny = (() => {
|
|
|
7445
7550
|
{ id: 18012 /* FileData */, data: image.data },
|
|
7446
7551
|
{ id: 18094 /* FileUID */, data: fileUid }
|
|
7447
7552
|
]
|
|
7448
|
-
};
|
|
7449
|
-
}
|
|
7553
|
+
});
|
|
7554
|
+
}
|
|
7555
|
+
for (const [key, value] of Object.entries(metadataTags.raw ?? {})) {
|
|
7556
|
+
if (!(value instanceof AttachedFile)) {
|
|
7557
|
+
continue;
|
|
7558
|
+
}
|
|
7559
|
+
const keyIsNumeric = /^\d+$/.test(key);
|
|
7560
|
+
if (!keyIsNumeric) {
|
|
7561
|
+
continue;
|
|
7562
|
+
}
|
|
7563
|
+
if (images.find((x) => x.mimeType === value.mimeType && uint8ArraysAreEqual(x.data, value.data))) {
|
|
7564
|
+
continue;
|
|
7565
|
+
}
|
|
7566
|
+
elements.push({
|
|
7567
|
+
id: 24999 /* AttachedFile */,
|
|
7568
|
+
data: [
|
|
7569
|
+
value.description !== void 0 ? { id: 18046 /* FileDescription */, data: new EBMLUnicodeString(value.description) } : null,
|
|
7570
|
+
{ id: 18030 /* FileName */, data: new EBMLUnicodeString(value.name ?? "") },
|
|
7571
|
+
{ id: 18016 /* FileMediaType */, data: value.mimeType ?? "" },
|
|
7572
|
+
{ id: 18012 /* FileData */, data: value.data },
|
|
7573
|
+
{ id: 18094 /* FileUID */, data: BigInt(key) }
|
|
7574
|
+
]
|
|
7575
|
+
});
|
|
7576
|
+
}
|
|
7577
|
+
if (elements.length === 0) {
|
|
7578
|
+
return;
|
|
7579
|
+
}
|
|
7580
|
+
this.attachmentsElement = { id: 423732329 /* Attachments */, data: elements };
|
|
7450
7581
|
}
|
|
7451
7582
|
createSegment() {
|
|
7452
7583
|
this.createTracks();
|
|
@@ -8054,11 +8185,11 @@ ${cue.notes ?? ""}`;
|
|
|
8054
8185
|
if (layer === 0) {
|
|
8055
8186
|
return 0;
|
|
8056
8187
|
} else if (layer === 1) {
|
|
8057
|
-
return Math.
|
|
8188
|
+
return Math.floor(144 * bitrate / (sampleRate << lowSamplingFrequency)) + padding;
|
|
8058
8189
|
} else if (layer === 2) {
|
|
8059
|
-
return Math.
|
|
8190
|
+
return Math.floor(144 * bitrate / sampleRate) + padding;
|
|
8060
8191
|
} else {
|
|
8061
|
-
return (Math.
|
|
8192
|
+
return (Math.floor(12 * bitrate / sampleRate) + padding) * 4;
|
|
8062
8193
|
}
|
|
8063
8194
|
};
|
|
8064
8195
|
var getXingOffset = (mpegVersionId, channel) => {
|
|
@@ -15591,7 +15722,7 @@ ${cue.notes ?? ""}`;
|
|
|
15591
15722
|
const abortController = new AbortController();
|
|
15592
15723
|
const response = await retriedFetch(
|
|
15593
15724
|
this._url,
|
|
15594
|
-
|
|
15725
|
+
mergeRequestInit(this._options.requestInit ?? {}, {
|
|
15595
15726
|
headers: {
|
|
15596
15727
|
// We could also send a non-range request to request the same bytes (all of them), but doing it like
|
|
15597
15728
|
// this is an easy way to check if the server supports range requests in the first place
|
|
@@ -15642,7 +15773,7 @@ ${cue.notes ?? ""}`;
|
|
|
15642
15773
|
abortController = new AbortController();
|
|
15643
15774
|
response = await retriedFetch(
|
|
15644
15775
|
this._url,
|
|
15645
|
-
|
|
15776
|
+
mergeRequestInit(this._options.requestInit ?? {}, {
|
|
15646
15777
|
headers: {
|
|
15647
15778
|
Range: `bytes=${worker.currentPos}-`
|
|
15648
15779
|
},
|
|
@@ -20073,12 +20204,23 @@ ${cue.notes ?? ""}`;
|
|
|
20073
20204
|
{
|
|
20074
20205
|
if (!this.currentSegment) break;
|
|
20075
20206
|
this.currentAttachedFile = {
|
|
20207
|
+
fileUid: null,
|
|
20076
20208
|
fileName: null,
|
|
20077
20209
|
fileMediaType: null,
|
|
20078
20210
|
fileData: null,
|
|
20079
20211
|
fileDescription: null
|
|
20080
20212
|
};
|
|
20081
20213
|
this.readContiguousElements(slice.slice(dataStartPos, size));
|
|
20214
|
+
const tags = this.currentSegment.metadataTags;
|
|
20215
|
+
if (this.currentAttachedFile.fileUid && this.currentAttachedFile.fileData) {
|
|
20216
|
+
tags.raw ??= {};
|
|
20217
|
+
tags.raw[this.currentAttachedFile.fileUid.toString()] = new AttachedFile(
|
|
20218
|
+
this.currentAttachedFile.fileData,
|
|
20219
|
+
this.currentAttachedFile.fileMediaType ?? void 0,
|
|
20220
|
+
this.currentAttachedFile.fileName ?? void 0,
|
|
20221
|
+
this.currentAttachedFile.fileDescription ?? void 0
|
|
20222
|
+
);
|
|
20223
|
+
}
|
|
20082
20224
|
if (this.currentAttachedFile.fileMediaType?.startsWith("image/") && this.currentAttachedFile.fileData) {
|
|
20083
20225
|
const fileName = this.currentAttachedFile.fileName;
|
|
20084
20226
|
let kind = "unknown";
|
|
@@ -20090,8 +20232,8 @@ ${cue.notes ?? ""}`;
|
|
|
20090
20232
|
kind = "coverBack";
|
|
20091
20233
|
}
|
|
20092
20234
|
}
|
|
20093
|
-
|
|
20094
|
-
|
|
20235
|
+
tags.images ??= [];
|
|
20236
|
+
tags.images.push({
|
|
20095
20237
|
data: this.currentAttachedFile.fileData,
|
|
20096
20238
|
mimeType: this.currentAttachedFile.fileMediaType,
|
|
20097
20239
|
kind,
|
|
@@ -20103,6 +20245,13 @@ ${cue.notes ?? ""}`;
|
|
|
20103
20245
|
}
|
|
20104
20246
|
;
|
|
20105
20247
|
break;
|
|
20248
|
+
case 18094 /* FileUID */:
|
|
20249
|
+
{
|
|
20250
|
+
if (!this.currentAttachedFile) break;
|
|
20251
|
+
this.currentAttachedFile.fileUid = readUnsignedBigInt(slice, size);
|
|
20252
|
+
}
|
|
20253
|
+
;
|
|
20254
|
+
break;
|
|
20106
20255
|
case 18030 /* FileName */:
|
|
20107
20256
|
{
|
|
20108
20257
|
if (!this.currentAttachedFile) break;
|
|
@@ -22743,7 +22892,7 @@ ${cue.notes ?? ""}`;
|
|
|
22743
22892
|
if (id3V2HeaderFound) {
|
|
22744
22893
|
return true;
|
|
22745
22894
|
}
|
|
22746
|
-
currentPos = firstResult.startPos
|
|
22895
|
+
currentPos = firstResult.startPos + firstResult.header.totalSize;
|
|
22747
22896
|
const secondResult = await readNextFrameHeader(input._reader, currentPos, currentPos + FRAME_HEADER_SIZE);
|
|
22748
22897
|
if (!secondResult) {
|
|
22749
22898
|
return false;
|