mediabunny 1.25.2 → 1.25.4
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 +118 -43
- package/dist/bundles/mediabunny.min.cjs +7 -7
- package/dist/bundles/mediabunny.min.mjs +7 -7
- package/dist/bundles/mediabunny.mjs +118 -43
- package/dist/mediabunny.d.ts +6 -3
- package/dist/modules/src/codec-data.d.ts.map +1 -1
- package/dist/modules/src/codec-data.js +54 -0
- package/dist/modules/src/conversion.d.ts.map +1 -1
- package/dist/modules/src/conversion.js +5 -1
- package/dist/modules/src/misc.d.ts +1 -1
- package/dist/modules/src/misc.d.ts.map +1 -1
- package/dist/modules/src/misc.js +6 -6
- package/dist/modules/src/sample.d.ts.map +1 -1
- package/dist/modules/src/sample.js +42 -4
- package/dist/modules/src/source.d.ts +5 -2
- package/dist/modules/src/source.d.ts.map +1 -1
- package/dist/modules/src/source.js +26 -30
- package/dist/modules/src/target.d.ts +1 -1
- package/dist/modules/src/target.d.ts.map +1 -1
- package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/codec-data.ts +64 -3
- package/src/conversion.ts +5 -1
- package/src/isobmff/isobmff-boxes.ts +1 -1
- package/src/misc.ts +7 -7
- package/src/sample.ts +65 -4
- package/src/source.ts +32 -39
- package/src/target.ts +1 -1
- package/src/writer.ts +2 -2
|
@@ -262,19 +262,19 @@ var Mediabunny = (() => {
|
|
|
262
262
|
var toUint8Array = (source) => {
|
|
263
263
|
if (source.constructor === Uint8Array) {
|
|
264
264
|
return source;
|
|
265
|
-
} else if (source
|
|
266
|
-
return new Uint8Array(source);
|
|
267
|
-
} else {
|
|
265
|
+
} else if (ArrayBuffer.isView(source)) {
|
|
268
266
|
return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
267
|
+
} else {
|
|
268
|
+
return new Uint8Array(source);
|
|
269
269
|
}
|
|
270
270
|
};
|
|
271
271
|
var toDataView = (source) => {
|
|
272
272
|
if (source.constructor === DataView) {
|
|
273
273
|
return source;
|
|
274
|
-
} else if (source
|
|
275
|
-
return new DataView(source);
|
|
276
|
-
} else {
|
|
274
|
+
} else if (ArrayBuffer.isView(source)) {
|
|
277
275
|
return new DataView(source.buffer, source.byteOffset, source.byteLength);
|
|
276
|
+
} else {
|
|
277
|
+
return new DataView(source);
|
|
278
278
|
}
|
|
279
279
|
};
|
|
280
280
|
var textDecoder = /* @__PURE__ */ new TextDecoder();
|
|
@@ -2783,6 +2783,55 @@ var Mediabunny = (() => {
|
|
|
2783
2783
|
}
|
|
2784
2784
|
}
|
|
2785
2785
|
}
|
|
2786
|
+
const frameWidthBitsMinus1 = bitstream.readBits(4);
|
|
2787
|
+
const frameHeightBitsMinus1 = bitstream.readBits(4);
|
|
2788
|
+
const n1 = frameWidthBitsMinus1 + 1;
|
|
2789
|
+
bitstream.skipBits(n1);
|
|
2790
|
+
const n2 = frameHeightBitsMinus1 + 1;
|
|
2791
|
+
bitstream.skipBits(n2);
|
|
2792
|
+
let frameIdNumbersPresentFlag = 0;
|
|
2793
|
+
if (reducedStillPictureHeader) {
|
|
2794
|
+
frameIdNumbersPresentFlag = 0;
|
|
2795
|
+
} else {
|
|
2796
|
+
frameIdNumbersPresentFlag = bitstream.readBits(1);
|
|
2797
|
+
}
|
|
2798
|
+
if (frameIdNumbersPresentFlag) {
|
|
2799
|
+
bitstream.skipBits(4);
|
|
2800
|
+
bitstream.skipBits(3);
|
|
2801
|
+
}
|
|
2802
|
+
bitstream.skipBits(1);
|
|
2803
|
+
bitstream.skipBits(1);
|
|
2804
|
+
bitstream.skipBits(1);
|
|
2805
|
+
if (!reducedStillPictureHeader) {
|
|
2806
|
+
bitstream.skipBits(1);
|
|
2807
|
+
bitstream.skipBits(1);
|
|
2808
|
+
bitstream.skipBits(1);
|
|
2809
|
+
bitstream.skipBits(1);
|
|
2810
|
+
const enableOrderHint = bitstream.readBits(1);
|
|
2811
|
+
if (enableOrderHint) {
|
|
2812
|
+
bitstream.skipBits(1);
|
|
2813
|
+
bitstream.skipBits(1);
|
|
2814
|
+
}
|
|
2815
|
+
const seqChooseScreenContentTools = bitstream.readBits(1);
|
|
2816
|
+
let seqForceScreenContentTools = 0;
|
|
2817
|
+
if (seqChooseScreenContentTools) {
|
|
2818
|
+
seqForceScreenContentTools = 2;
|
|
2819
|
+
} else {
|
|
2820
|
+
seqForceScreenContentTools = bitstream.readBits(1);
|
|
2821
|
+
}
|
|
2822
|
+
if (seqForceScreenContentTools > 0) {
|
|
2823
|
+
const seqChooseIntegerMv = bitstream.readBits(1);
|
|
2824
|
+
if (!seqChooseIntegerMv) {
|
|
2825
|
+
bitstream.skipBits(1);
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
if (enableOrderHint) {
|
|
2829
|
+
bitstream.skipBits(3);
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
bitstream.skipBits(1);
|
|
2833
|
+
bitstream.skipBits(1);
|
|
2834
|
+
bitstream.skipBits(1);
|
|
2786
2835
|
const highBitdepth = bitstream.readBits(1);
|
|
2787
2836
|
let bitDepth = 8;
|
|
2788
2837
|
if (seqProfile === 2 && highBitdepth) {
|
|
@@ -3700,11 +3749,40 @@ var Mediabunny = (() => {
|
|
|
3700
3749
|
|
|
3701
3750
|
// src/sample.ts
|
|
3702
3751
|
polyfillSymbolDispose();
|
|
3752
|
+
var lastVideoGcErrorLog = -Infinity;
|
|
3753
|
+
var lastAudioGcErrorLog = -Infinity;
|
|
3754
|
+
var finalizationRegistry = null;
|
|
3755
|
+
if (typeof FinalizationRegistry !== "undefined") {
|
|
3756
|
+
finalizationRegistry = new FinalizationRegistry((value) => {
|
|
3757
|
+
const now = Date.now();
|
|
3758
|
+
if (value.type === "video") {
|
|
3759
|
+
if (now - lastVideoGcErrorLog >= 1e3) {
|
|
3760
|
+
console.error(
|
|
3761
|
+
`A VideoSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your VideoSamples as soon as you're done using them.`
|
|
3762
|
+
);
|
|
3763
|
+
lastVideoGcErrorLog = now;
|
|
3764
|
+
}
|
|
3765
|
+
if (typeof VideoFrame !== "undefined" && value.data instanceof VideoFrame) {
|
|
3766
|
+
value.data.close();
|
|
3767
|
+
}
|
|
3768
|
+
} else {
|
|
3769
|
+
if (now - lastAudioGcErrorLog >= 1e3) {
|
|
3770
|
+
console.error(
|
|
3771
|
+
`An AudioSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your AudioSamples as soon as you're done using them.`
|
|
3772
|
+
);
|
|
3773
|
+
lastAudioGcErrorLog = now;
|
|
3774
|
+
}
|
|
3775
|
+
if (typeof AudioData !== "undefined" && value.data instanceof AudioData) {
|
|
3776
|
+
value.data.close();
|
|
3777
|
+
}
|
|
3778
|
+
}
|
|
3779
|
+
});
|
|
3780
|
+
}
|
|
3703
3781
|
var VideoSample = class _VideoSample {
|
|
3704
3782
|
constructor(data, init) {
|
|
3705
3783
|
/** @internal */
|
|
3706
3784
|
this._closed = false;
|
|
3707
|
-
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|
3785
|
+
if (data instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && data instanceof SharedArrayBuffer || ArrayBuffer.isView(data)) {
|
|
3708
3786
|
if (!init || typeof init !== "object") {
|
|
3709
3787
|
throw new TypeError("init must be an object.");
|
|
3710
3788
|
}
|
|
@@ -3814,6 +3892,7 @@ var Mediabunny = (() => {
|
|
|
3814
3892
|
} else {
|
|
3815
3893
|
throw new TypeError("Invalid data type: Must be a BufferSource or CanvasImageSource.");
|
|
3816
3894
|
}
|
|
3895
|
+
finalizationRegistry?.register(this, { type: "video", data: this._data }, this);
|
|
3817
3896
|
}
|
|
3818
3897
|
/** The width of the frame in pixels after rotation. */
|
|
3819
3898
|
get displayWidth() {
|
|
@@ -3880,6 +3959,7 @@ var Mediabunny = (() => {
|
|
|
3880
3959
|
if (this._closed) {
|
|
3881
3960
|
return;
|
|
3882
3961
|
}
|
|
3962
|
+
finalizationRegistry?.unregister(this);
|
|
3883
3963
|
if (isVideoFrame(this._data)) {
|
|
3884
3964
|
this._data.close();
|
|
3885
3965
|
} else {
|
|
@@ -4258,6 +4338,7 @@ var Mediabunny = (() => {
|
|
|
4258
4338
|
}
|
|
4259
4339
|
this._data = dataBuffer;
|
|
4260
4340
|
}
|
|
4341
|
+
finalizationRegistry?.register(this, { type: "audio", data: this._data }, this);
|
|
4261
4342
|
}
|
|
4262
4343
|
/** The presentation timestamp of the sample in microseconds. */
|
|
4263
4344
|
get microsecondTimestamp() {
|
|
@@ -4402,7 +4483,7 @@ var Mediabunny = (() => {
|
|
|
4402
4483
|
}
|
|
4403
4484
|
} else {
|
|
4404
4485
|
const uint8Data = this._data;
|
|
4405
|
-
const srcView =
|
|
4486
|
+
const srcView = toDataView(uint8Data);
|
|
4406
4487
|
const srcFormat = this.format;
|
|
4407
4488
|
const readFn = getReadFunction(srcFormat);
|
|
4408
4489
|
const srcBytesPerSample = getBytesPerSample(srcFormat);
|
|
@@ -4463,6 +4544,7 @@ var Mediabunny = (() => {
|
|
|
4463
4544
|
if (this._closed) {
|
|
4464
4545
|
return;
|
|
4465
4546
|
}
|
|
4547
|
+
finalizationRegistry?.unregister(this);
|
|
4466
4548
|
if (isAudioData(this._data)) {
|
|
4467
4549
|
this._data.close();
|
|
4468
4550
|
} else {
|
|
@@ -4516,7 +4598,8 @@ var Mediabunny = (() => {
|
|
|
4516
4598
|
numberOfFrames: this.numberOfFrames,
|
|
4517
4599
|
numberOfChannels: this.numberOfChannels,
|
|
4518
4600
|
timestamp: this.microsecondTimestamp,
|
|
4519
|
-
data: this._data
|
|
4601
|
+
data: this._data.buffer instanceof ArrayBuffer ? this._data.buffer : this._data.slice()
|
|
4602
|
+
// In the case of SharedArrayBuffer, convert to ArrayBuffer
|
|
4520
4603
|
});
|
|
4521
4604
|
}
|
|
4522
4605
|
}
|
|
@@ -15241,10 +15324,13 @@ var Mediabunny = (() => {
|
|
|
15241
15324
|
}
|
|
15242
15325
|
};
|
|
15243
15326
|
var BufferSource = class extends Source {
|
|
15244
|
-
/**
|
|
15327
|
+
/**
|
|
15328
|
+
* Creates a new {@link BufferSource} backed by the specified `ArrayBuffer`, `SharedArrayBuffer`,
|
|
15329
|
+
* or `ArrayBufferView`.
|
|
15330
|
+
*/
|
|
15245
15331
|
constructor(buffer) {
|
|
15246
|
-
if (!(buffer instanceof ArrayBuffer) && !ArrayBuffer.isView(buffer)) {
|
|
15247
|
-
throw new TypeError("buffer must be an ArrayBuffer or ArrayBufferView.");
|
|
15332
|
+
if (!(buffer instanceof ArrayBuffer) && !(typeof SharedArrayBuffer !== "undefined" && buffer instanceof SharedArrayBuffer) && !ArrayBuffer.isView(buffer)) {
|
|
15333
|
+
throw new TypeError("buffer must be an ArrayBuffer, SharedArrayBuffer, or ArrayBufferView.");
|
|
15248
15334
|
}
|
|
15249
15335
|
super();
|
|
15250
15336
|
/** @internal */
|
|
@@ -15325,10 +15411,7 @@ var Mediabunny = (() => {
|
|
|
15325
15411
|
const { done, value } = await reader.read();
|
|
15326
15412
|
if (done) {
|
|
15327
15413
|
this._orchestrator.forgetWorker(worker);
|
|
15328
|
-
|
|
15329
|
-
throw new Error("Blob reader stopped unexpectedly before all requested data was read.");
|
|
15330
|
-
}
|
|
15331
|
-
break;
|
|
15414
|
+
throw new Error("Blob reader stopped unexpectedly before all requested data was read.");
|
|
15332
15415
|
}
|
|
15333
15416
|
if (worker.aborted) {
|
|
15334
15417
|
break;
|
|
@@ -15431,7 +15514,7 @@ var Mediabunny = (() => {
|
|
|
15431
15514
|
let worker;
|
|
15432
15515
|
let fileSize;
|
|
15433
15516
|
if (response.status === 206) {
|
|
15434
|
-
fileSize = this.
|
|
15517
|
+
fileSize = this._getTotalLengthFromRangeResponse(response);
|
|
15435
15518
|
worker = this._orchestrator.createWorker(0, Math.min(fileSize, URL_SOURCE_MIN_LOAD_AMOUNT));
|
|
15436
15519
|
} else {
|
|
15437
15520
|
const contentLength = response.headers.get("Content-Length");
|
|
@@ -15486,13 +15569,6 @@ var Mediabunny = (() => {
|
|
|
15486
15569
|
"HTTP server did not respond with 206 Partial Content to a range request. To enable efficient media file streaming across a network, please make sure your server supports range requests."
|
|
15487
15570
|
);
|
|
15488
15571
|
}
|
|
15489
|
-
const length = this._getPartialLengthFromRangeResponse(response);
|
|
15490
|
-
const required = worker.targetPos - worker.currentPos;
|
|
15491
|
-
if (length < required) {
|
|
15492
|
-
throw new Error(
|
|
15493
|
-
`HTTP response unexpectedly too short: Needed at least ${required} bytes, got only ${length}.`
|
|
15494
|
-
);
|
|
15495
|
-
}
|
|
15496
15572
|
if (!response.body) {
|
|
15497
15573
|
throw new Error(
|
|
15498
15574
|
"Missing HTTP response body stream. The used fetch function must provide the response body as a ReadableStream."
|
|
@@ -15526,14 +15602,12 @@ var Mediabunny = (() => {
|
|
|
15526
15602
|
}
|
|
15527
15603
|
const { done, value } = readResult;
|
|
15528
15604
|
if (done) {
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
);
|
|
15605
|
+
if (worker.currentPos >= worker.targetPos) {
|
|
15606
|
+
this._orchestrator.forgetWorker(worker);
|
|
15607
|
+
worker.running = false;
|
|
15608
|
+
return;
|
|
15534
15609
|
}
|
|
15535
|
-
|
|
15536
|
-
return;
|
|
15610
|
+
break;
|
|
15537
15611
|
}
|
|
15538
15612
|
this.onread?.(worker.currentPos, worker.currentPos + value.length);
|
|
15539
15613
|
this._orchestrator.supplyWorkerData(worker, value);
|
|
@@ -15545,24 +15619,21 @@ var Mediabunny = (() => {
|
|
|
15545
15619
|
worker.running = false;
|
|
15546
15620
|
}
|
|
15547
15621
|
/** @internal */
|
|
15548
|
-
|
|
15622
|
+
_getTotalLengthFromRangeResponse(response) {
|
|
15549
15623
|
const contentRange = response.headers.get("Content-Range");
|
|
15550
15624
|
if (contentRange) {
|
|
15551
15625
|
const match = /\/(\d+)/.exec(contentRange);
|
|
15552
15626
|
if (match) {
|
|
15553
15627
|
return Number(match[1]);
|
|
15554
|
-
} else {
|
|
15555
|
-
throw new Error(`Invalid Content-Range header: ${contentRange}`);
|
|
15556
15628
|
}
|
|
15629
|
+
}
|
|
15630
|
+
const contentLength = response.headers.get("Content-Length");
|
|
15631
|
+
if (contentLength) {
|
|
15632
|
+
return Number(contentLength);
|
|
15557
15633
|
} else {
|
|
15558
|
-
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
} else {
|
|
15562
|
-
throw new Error(
|
|
15563
|
-
"Partial HTTP response (status 206) must surface either Content-Range or Content-Length header."
|
|
15564
|
-
);
|
|
15565
|
-
}
|
|
15634
|
+
throw new Error(
|
|
15635
|
+
"Partial HTTP response (status 206) must surface either Content-Range or Content-Length header."
|
|
15636
|
+
);
|
|
15566
15637
|
}
|
|
15567
15638
|
}
|
|
15568
15639
|
/** @internal */
|
|
@@ -25117,7 +25188,10 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
25117
25188
|
targetSampleRate,
|
|
25118
25189
|
startTime: this._startTimestamp,
|
|
25119
25190
|
endTime: this._endTimestamp,
|
|
25120
|
-
onSample: (sample) =>
|
|
25191
|
+
onSample: async (sample) => {
|
|
25192
|
+
await this._registerAudioSample(track, trackOptions, source, sample);
|
|
25193
|
+
sample.close();
|
|
25194
|
+
}
|
|
25121
25195
|
});
|
|
25122
25196
|
const sink = new AudioSampleSink(track);
|
|
25123
25197
|
const iterator = sink.samples(this._startTimestamp, this._endTimestamp);
|
|
@@ -25126,6 +25200,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
|
|
|
25126
25200
|
return;
|
|
25127
25201
|
}
|
|
25128
25202
|
await resampler.add(sample);
|
|
25203
|
+
sample.close();
|
|
25129
25204
|
}
|
|
25130
25205
|
await resampler.finalize();
|
|
25131
25206
|
source.close();
|