mediabunny 1.15.0 → 1.15.2
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 +1 -1
- package/dist/bundles/mediabunny.cjs +84 -21
- package/dist/bundles/mediabunny.min.cjs +4 -4
- package/dist/bundles/mediabunny.min.mjs +4 -4
- package/dist/bundles/mediabunny.mjs +96 -21
- package/dist/mediabunny.d.ts +5 -4
- package/dist/modules/src/conversion.d.ts +4 -4
- package/dist/modules/src/conversion.d.ts.map +1 -1
- package/dist/modules/src/conversion.js +14 -5
- package/dist/modules/src/isobmff/isobmff-demuxer.d.ts.map +1 -1
- package/dist/modules/src/isobmff/isobmff-demuxer.js +16 -0
- package/dist/modules/src/media-sink.d.ts.map +1 -1
- package/dist/modules/src/media-sink.js +11 -3
- package/dist/modules/src/media-source.d.ts.map +1 -1
- package/dist/modules/src/media-source.js +11 -3
- package/dist/modules/src/misc.d.ts +1 -0
- package/dist/modules/src/misc.d.ts.map +1 -1
- package/dist/modules/src/misc.js +7 -0
- package/dist/modules/src/node.d.ts +9 -0
- package/dist/modules/src/node.d.ts.map +1 -0
- package/dist/modules/src/node.js +9 -0
- package/dist/modules/src/sample.d.ts +1 -0
- package/dist/modules/src/sample.d.ts.map +1 -1
- package/dist/modules/src/sample.js +10 -6
- package/dist/modules/src/source.d.ts.map +1 -1
- package/dist/modules/src/source.js +4 -4
- package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -1
- package/src/conversion.ts +22 -9
- package/src/isobmff/isobmff-demuxer.ts +15 -0
- package/src/media-sink.ts +10 -3
- package/src/media-source.ts +19 -4
- package/src/misc.ts +9 -0
- package/src/node.ts +11 -0
- package/src/sample.ts +11 -5
- package/src/source.ts +6 -4
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ Core features include:
|
|
|
50
50
|
- **Wide format support**: Read and write MP4, MOV, WebM, MKV, WAVE, MP3, Ogg, ADTS
|
|
51
51
|
- **Built-in encoding & decoding**: Supports 25+ video, audio, and subtitle codecs, hardware-accelerated using the WebCodecs API
|
|
52
52
|
- **High precision**: Fine-grained, microsecond-accurate reading and writing operations
|
|
53
|
-
- **Conversion API**: Easy-to-use API with features such as transmuxing, transcoding, resizing, rotation, resampling, trimming, and more
|
|
53
|
+
- **Conversion API**: Easy-to-use API with features such as transmuxing, transcoding, resizing, rotation, cropping, resampling, trimming, and more
|
|
54
54
|
- **Streaming I/O**: Handle reading & writing files of any size with memory-efficient streaming
|
|
55
55
|
- **Tree-shakable**: Only bundle what you use (as small as 5 kB gzipped)
|
|
56
56
|
- **Zero dependencies**: Implemented in highly performant TypeScript
|
|
@@ -7,10 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
"use strict";
|
|
9
9
|
var Mediabunny = (() => {
|
|
10
|
+
var __create = Object.create;
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
};
|
|
14
19
|
var __export = (target, all) => {
|
|
15
20
|
for (var name in all)
|
|
16
21
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -23,8 +28,22 @@ var Mediabunny = (() => {
|
|
|
23
28
|
}
|
|
24
29
|
return to;
|
|
25
30
|
};
|
|
31
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
32
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
33
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
34
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
35
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
36
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
37
|
+
mod
|
|
38
|
+
));
|
|
26
39
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
40
|
|
|
41
|
+
// (disabled):src/node
|
|
42
|
+
var require_node = __commonJS({
|
|
43
|
+
"(disabled):src/node"() {
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
28
47
|
// src/index.ts
|
|
29
48
|
var index_exports = {};
|
|
30
49
|
__export(index_exports, {
|
|
@@ -586,6 +605,13 @@ var Mediabunny = (() => {
|
|
|
586
605
|
isSafariCache = result;
|
|
587
606
|
return result;
|
|
588
607
|
};
|
|
608
|
+
var isFirefoxCache = null;
|
|
609
|
+
var isFirefox = () => {
|
|
610
|
+
if (isFirefoxCache !== null) {
|
|
611
|
+
return isFirefoxCache;
|
|
612
|
+
}
|
|
613
|
+
return isFirefoxCache = typeof navigator !== "undefined" && navigator.userAgent?.includes("Firefox");
|
|
614
|
+
};
|
|
589
615
|
var coalesceIndex = (a, b) => {
|
|
590
616
|
return a !== -1 ? a : b;
|
|
591
617
|
};
|
|
@@ -9321,7 +9347,8 @@ ${cue.notes ?? ""}`;
|
|
|
9321
9347
|
return new _VideoSample(
|
|
9322
9348
|
new VideoFrame(data, {
|
|
9323
9349
|
timestamp: Math.trunc(init.timestamp * SECOND_TO_MICROSECOND_FACTOR),
|
|
9324
|
-
|
|
9350
|
+
// Drag 0 to undefined
|
|
9351
|
+
duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || void 0
|
|
9325
9352
|
}),
|
|
9326
9353
|
init
|
|
9327
9354
|
);
|
|
@@ -9342,7 +9369,11 @@ ${cue.notes ?? ""}`;
|
|
|
9342
9369
|
throw new TypeError("Could not determine dimensions.");
|
|
9343
9370
|
}
|
|
9344
9371
|
const canvas = new OffscreenCanvas(width, height);
|
|
9345
|
-
const context = canvas.getContext("2d", {
|
|
9372
|
+
const context = canvas.getContext("2d", {
|
|
9373
|
+
alpha: isFirefox(),
|
|
9374
|
+
// Firefox has VideoFrame glitches with opaque canvases
|
|
9375
|
+
willReadFrequently: true
|
|
9376
|
+
});
|
|
9346
9377
|
assert(context);
|
|
9347
9378
|
context.drawImage(data, 0, 0);
|
|
9348
9379
|
this._data = canvas;
|
|
@@ -9457,7 +9488,7 @@ ${cue.notes ?? ""}`;
|
|
|
9457
9488
|
dest.set(this._data);
|
|
9458
9489
|
} else {
|
|
9459
9490
|
const canvas = this._data;
|
|
9460
|
-
const context = canvas.getContext("2d"
|
|
9491
|
+
const context = canvas.getContext("2d");
|
|
9461
9492
|
assert(context);
|
|
9462
9493
|
const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
|
|
9463
9494
|
const dest = toUint8Array(destination);
|
|
@@ -9485,13 +9516,13 @@ ${cue.notes ?? ""}`;
|
|
|
9485
9516
|
codedWidth: this.codedWidth,
|
|
9486
9517
|
codedHeight: this.codedHeight,
|
|
9487
9518
|
timestamp: this.microsecondTimestamp,
|
|
9488
|
-
duration: this.microsecondDuration,
|
|
9519
|
+
duration: this.microsecondDuration || void 0,
|
|
9489
9520
|
colorSpace: this.colorSpace
|
|
9490
9521
|
});
|
|
9491
9522
|
} else {
|
|
9492
9523
|
return new VideoFrame(this._data, {
|
|
9493
9524
|
timestamp: this.microsecondTimestamp,
|
|
9494
|
-
duration: this.microsecondDuration
|
|
9525
|
+
duration: this.microsecondDuration || void 0
|
|
9495
9526
|
});
|
|
9496
9527
|
}
|
|
9497
9528
|
}
|
|
@@ -10988,11 +11019,19 @@ ${cue.notes ?? ""}`;
|
|
|
10988
11019
|
if (this._canvasPool.length > 0) {
|
|
10989
11020
|
this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;
|
|
10990
11021
|
}
|
|
10991
|
-
const context = canvas.getContext("2d", {
|
|
11022
|
+
const context = canvas.getContext("2d", {
|
|
11023
|
+
alpha: isFirefox()
|
|
11024
|
+
// Firefox has VideoFrame glitches with opaque canvases
|
|
11025
|
+
});
|
|
10992
11026
|
assert(context);
|
|
10993
11027
|
context.resetTransform();
|
|
10994
11028
|
if (!canvasIsNew) {
|
|
10995
|
-
|
|
11029
|
+
if (isFirefox()) {
|
|
11030
|
+
context.fillStyle = "black";
|
|
11031
|
+
context.fillRect(0, 0, this._width, this._height);
|
|
11032
|
+
} else {
|
|
11033
|
+
context.clearRect(0, 0, this._width, this._height);
|
|
11034
|
+
}
|
|
10996
11035
|
}
|
|
10997
11036
|
sample.drawWithFit(context, {
|
|
10998
11037
|
fit: this._fit,
|
|
@@ -13280,10 +13319,18 @@ ${cue.notes ?? ""}`;
|
|
|
13280
13319
|
}
|
|
13281
13320
|
canvasIsNew = true;
|
|
13282
13321
|
}
|
|
13283
|
-
const context = this.resizeCanvas.getContext("2d", {
|
|
13322
|
+
const context = this.resizeCanvas.getContext("2d", {
|
|
13323
|
+
alpha: isFirefox()
|
|
13324
|
+
// Firefox has VideoFrame glitches with opaque canvases
|
|
13325
|
+
});
|
|
13284
13326
|
assert(context);
|
|
13285
13327
|
if (!canvasIsNew) {
|
|
13286
|
-
|
|
13328
|
+
if (isFirefox()) {
|
|
13329
|
+
context.fillStyle = "black";
|
|
13330
|
+
context.fillRect(0, 0, this.codedWidth, this.codedHeight);
|
|
13331
|
+
} else {
|
|
13332
|
+
context.clearRect(0, 0, this.codedWidth, this.codedHeight);
|
|
13333
|
+
}
|
|
13287
13334
|
}
|
|
13288
13335
|
videoSample.drawWithFit(context, { fit: sizeChangeBehavior });
|
|
13289
13336
|
if (shouldClose) {
|
|
@@ -14594,6 +14641,8 @@ ${cue.notes ?? ""}`;
|
|
|
14594
14641
|
};
|
|
14595
14642
|
|
|
14596
14643
|
// src/source.ts
|
|
14644
|
+
var nodeAlias = __toESM(require_node(), 1);
|
|
14645
|
+
var node = nodeAlias;
|
|
14597
14646
|
var Source = class {
|
|
14598
14647
|
constructor() {
|
|
14599
14648
|
/** @internal */
|
|
@@ -14916,18 +14965,13 @@ ${cue.notes ?? ""}`;
|
|
|
14916
14965
|
let fileHandle = null;
|
|
14917
14966
|
this._streamSource = new StreamSource({
|
|
14918
14967
|
getSize: async () => {
|
|
14919
|
-
|
|
14920
|
-
const fs = await import(
|
|
14921
|
-
/* @vite-ignore */
|
|
14922
|
-
FS_MODULE_NAME
|
|
14923
|
-
);
|
|
14924
|
-
fileHandle = await fs.open(filePath, "r");
|
|
14968
|
+
fileHandle = await node.fs.open(filePath, "r");
|
|
14925
14969
|
const stats = await fileHandle.stat();
|
|
14926
14970
|
return stats.size;
|
|
14927
14971
|
},
|
|
14928
14972
|
read: async (start, end) => {
|
|
14929
14973
|
assert(fileHandle);
|
|
14930
|
-
const buffer =
|
|
14974
|
+
const buffer = new Uint8Array(end - start);
|
|
14931
14975
|
await fileHandle.read(buffer, 0, end - start, start);
|
|
14932
14976
|
return buffer;
|
|
14933
14977
|
},
|
|
@@ -17479,6 +17523,22 @@ ${cue.notes ?? ""}`;
|
|
|
17479
17523
|
}
|
|
17480
17524
|
;
|
|
17481
17525
|
break;
|
|
17526
|
+
case "track":
|
|
17527
|
+
{
|
|
17528
|
+
if (typeof data === "string") {
|
|
17529
|
+
const parts = data.split("/");
|
|
17530
|
+
const trackNum = Number.parseInt(parts[0], 10);
|
|
17531
|
+
const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
|
|
17532
|
+
if (Number.isInteger(trackNum) && trackNum > 0) {
|
|
17533
|
+
this.metadataTags.trackNumber ??= trackNum;
|
|
17534
|
+
}
|
|
17535
|
+
if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
|
|
17536
|
+
this.metadataTags.tracksTotal ??= tracksTotal;
|
|
17537
|
+
}
|
|
17538
|
+
}
|
|
17539
|
+
}
|
|
17540
|
+
;
|
|
17541
|
+
break;
|
|
17482
17542
|
case "trkn":
|
|
17483
17543
|
{
|
|
17484
17544
|
if (data instanceof Uint8Array) {
|
|
@@ -21805,8 +21865,8 @@ ${cue.notes ?? ""}`;
|
|
|
21805
21865
|
if (!(options.output instanceof Output)) {
|
|
21806
21866
|
throw new TypeError("options.output must be an Output.");
|
|
21807
21867
|
}
|
|
21808
|
-
if (options.output._tracks.length > 0 || options.output.state !== "pending") {
|
|
21809
|
-
throw new TypeError("options.output must be fresh: no tracks added and not started.");
|
|
21868
|
+
if (options.output._tracks.length > 0 || Object.keys(options.output._metadataTags).length > 0 || options.output.state !== "pending") {
|
|
21869
|
+
throw new TypeError("options.output must be fresh: no tracks or metadata tags added and not started.");
|
|
21810
21870
|
}
|
|
21811
21871
|
if (typeof options.video !== "function") {
|
|
21812
21872
|
validateVideoOptions(options.video);
|
|
@@ -21828,8 +21888,11 @@ ${cue.notes ?? ""}`;
|
|
|
21828
21888
|
if (options.trim?.start !== void 0 && options.trim.end !== void 0 && options.trim.start >= options.trim.end) {
|
|
21829
21889
|
throw new TypeError("options.trim.start must be less than options.trim.end.");
|
|
21830
21890
|
}
|
|
21831
|
-
if (options.tags !== void 0 && typeof options.tags !== "function") {
|
|
21832
|
-
throw new TypeError("options.tags, when provided, must be a function.");
|
|
21891
|
+
if (options.tags !== void 0 && (typeof options.tags !== "object" || !options.tags) && typeof options.tags !== "function") {
|
|
21892
|
+
throw new TypeError("options.tags, when provided, must be an object or a function.");
|
|
21893
|
+
}
|
|
21894
|
+
if (typeof options.tags === "object") {
|
|
21895
|
+
validateMetadataTags(options.tags);
|
|
21833
21896
|
}
|
|
21834
21897
|
this._options = options;
|
|
21835
21898
|
this.input = options.input;
|
|
@@ -21911,7 +21974,7 @@ ${cue.notes ?? ""}`;
|
|
|
21911
21974
|
const inputTags = await this.input.getMetadataTags();
|
|
21912
21975
|
let outputTags;
|
|
21913
21976
|
if (this._options.tags) {
|
|
21914
|
-
const result = await this._options.tags(inputTags);
|
|
21977
|
+
const result = typeof this._options.tags === "function" ? await this._options.tags(inputTags) : this._options.tags;
|
|
21915
21978
|
validateMetadataTags(result);
|
|
21916
21979
|
outputTags = result;
|
|
21917
21980
|
} else {
|