mediabunny 1.1.1 → 1.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/dist/bundles/mediabunny.cjs +406 -141
- package/dist/bundles/mediabunny.min.cjs +4 -4
- package/dist/bundles/mediabunny.min.mjs +4 -4
- package/dist/bundles/mediabunny.mjs +406 -141
- package/dist/mediabunny.d.ts +31 -2
- package/dist/modules/codec-data.d.ts +9 -0
- package/dist/modules/codec-data.d.ts.map +1 -1
- package/dist/modules/codec-data.js +278 -145
- package/dist/modules/codec.js +2 -2
- package/dist/modules/conversion.js +8 -8
- package/dist/modules/index.js +14 -14
- package/dist/modules/input-format.js +12 -12
- package/dist/modules/input-track.d.ts +16 -3
- package/dist/modules/input-track.d.ts.map +1 -1
- package/dist/modules/input-track.js +34 -5
- package/dist/modules/input.js +4 -4
- package/dist/modules/isobmff/isobmff-boxes.js +5 -5
- package/dist/modules/isobmff/isobmff-demuxer.js +9 -9
- package/dist/modules/isobmff/isobmff-muxer.js +10 -10
- package/dist/modules/matroska/matroska-demuxer.js +9 -9
- package/dist/modules/matroska/matroska-muxer.d.ts.map +1 -1
- package/dist/modules/matroska/matroska-muxer.js +9 -11
- package/dist/modules/media-sink.d.ts +11 -0
- package/dist/modules/media-sink.d.ts.map +1 -1
- package/dist/modules/media-sink.js +70 -17
- package/dist/modules/media-source.js +7 -7
- package/dist/modules/misc.d.ts +1 -1
- package/dist/modules/misc.d.ts.map +1 -1
- package/dist/modules/misc.js +4 -1
- package/dist/modules/mp3/mp3-demuxer.js +6 -6
- package/dist/modules/mp3/mp3-muxer.js +4 -4
- package/dist/modules/mp3/mp3-reader.js +2 -2
- package/dist/modules/mp3/mp3-writer.js +1 -1
- package/dist/modules/muxer.js +1 -1
- package/dist/modules/ogg/ogg-demuxer.js +9 -9
- package/dist/modules/ogg/ogg-misc.js +2 -2
- package/dist/modules/ogg/ogg-muxer.js +6 -6
- package/dist/modules/ogg/ogg-reader.js +1 -1
- package/dist/modules/output-format.d.ts +5 -0
- package/dist/modules/output-format.d.ts.map +1 -1
- package/dist/modules/output-format.js +9 -6
- package/dist/modules/output.js +4 -4
- package/dist/modules/packet.js +1 -1
- package/dist/modules/reader.js +1 -1
- package/dist/modules/sample.js +1 -1
- package/dist/modules/source.js +1 -1
- package/dist/modules/target.js +1 -1
- package/dist/modules/wave/riff-reader.d.ts +1 -0
- package/dist/modules/wave/riff-reader.d.ts.map +1 -1
- package/dist/modules/wave/riff-reader.js +13 -0
- package/dist/modules/wave/riff-writer.d.ts +2 -1
- package/dist/modules/wave/riff-writer.d.ts.map +1 -1
- package/dist/modules/wave/riff-writer.js +8 -3
- package/dist/modules/wave/wave-demuxer.d.ts.map +1 -1
- package/dist/modules/wave/wave-demuxer.js +24 -9
- package/dist/modules/wave/wave-muxer.d.ts +3 -0
- package/dist/modules/wave/wave-muxer.d.ts.map +1 -1
- package/dist/modules/wave/wave-muxer.js +55 -14
- package/dist/modules/writer.js +1 -1
- package/package.json +2 -2
- package/src/codec-data.ts +317 -155
- package/src/conversion.ts +1 -1
- package/src/input-format.ts +1 -1
- package/src/input-track.ts +42 -3
- package/src/matroska/matroska-muxer.ts +1 -2
- package/src/media-sink.ts +88 -10
- package/src/misc.ts +6 -2
- package/src/output-format.ts +9 -0
- package/src/wave/riff-reader.ts +15 -0
- package/src/wave/riff-writer.ts +9 -3
- package/src/wave/wave-demuxer.ts +24 -3
- package/src/wave/wave-muxer.ts +57 -9
|
@@ -159,6 +159,9 @@ var Mediabunny = (() => {
|
|
|
159
159
|
return bit;
|
|
160
160
|
}
|
|
161
161
|
readBits(n) {
|
|
162
|
+
if (n === 1) {
|
|
163
|
+
return this.readBit();
|
|
164
|
+
}
|
|
162
165
|
let result = 0;
|
|
163
166
|
for (let i = 0; i < n; i++) {
|
|
164
167
|
result <<= 1;
|
|
@@ -189,7 +192,7 @@ var Mediabunny = (() => {
|
|
|
189
192
|
};
|
|
190
193
|
var readExpGolomb = (bitstream) => {
|
|
191
194
|
let leadingZeroBits = 0;
|
|
192
|
-
while (bitstream.
|
|
195
|
+
while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {
|
|
193
196
|
leadingZeroBits++;
|
|
194
197
|
}
|
|
195
198
|
if (leadingZeroBits >= 32) {
|
|
@@ -1773,6 +1776,31 @@ var Mediabunny = (() => {
|
|
|
1773
1776
|
}
|
|
1774
1777
|
return nalUnits;
|
|
1775
1778
|
};
|
|
1779
|
+
var findNalUnitsInLengthPrefixed = (packetData, lengthSize) => {
|
|
1780
|
+
const nalUnits = [];
|
|
1781
|
+
let offset = 0;
|
|
1782
|
+
const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);
|
|
1783
|
+
while (offset + lengthSize <= packetData.length) {
|
|
1784
|
+
let nalUnitLength;
|
|
1785
|
+
if (lengthSize === 1) {
|
|
1786
|
+
nalUnitLength = dataView.getUint8(offset);
|
|
1787
|
+
} else if (lengthSize === 2) {
|
|
1788
|
+
nalUnitLength = dataView.getUint16(offset, false);
|
|
1789
|
+
} else if (lengthSize === 3) {
|
|
1790
|
+
nalUnitLength = (dataView.getUint16(offset, false) << 8) + dataView.getUint8(offset + 2);
|
|
1791
|
+
} else if (lengthSize === 4) {
|
|
1792
|
+
nalUnitLength = dataView.getUint32(offset, false);
|
|
1793
|
+
} else {
|
|
1794
|
+
assertNever(lengthSize);
|
|
1795
|
+
assert(false);
|
|
1796
|
+
}
|
|
1797
|
+
offset += lengthSize;
|
|
1798
|
+
const nalUnit = packetData.subarray(offset, offset + nalUnitLength);
|
|
1799
|
+
nalUnits.push(nalUnit);
|
|
1800
|
+
offset += nalUnitLength;
|
|
1801
|
+
}
|
|
1802
|
+
return nalUnits;
|
|
1803
|
+
};
|
|
1776
1804
|
var removeEmulationPreventionBytes = (data) => {
|
|
1777
1805
|
const result = [];
|
|
1778
1806
|
const len = data.length;
|
|
@@ -2348,22 +2376,6 @@ var Mediabunny = (() => {
|
|
|
2348
2376
|
return new Uint8Array(bytes2);
|
|
2349
2377
|
};
|
|
2350
2378
|
var extractVp9CodecInfoFromPacket = (packet) => {
|
|
2351
|
-
const lastByte = packet[packet.length - 1];
|
|
2352
|
-
if (lastByte && (lastByte & 224) === 192) {
|
|
2353
|
-
const bytesPerFrameSize = ((lastByte & 24) >> 3) + 1;
|
|
2354
|
-
const numFrames = (lastByte & 7) + 1;
|
|
2355
|
-
const indexSize = 2 + numFrames * bytesPerFrameSize;
|
|
2356
|
-
if (packet[packet.length - indexSize] !== lastByte) {
|
|
2357
|
-
return null;
|
|
2358
|
-
}
|
|
2359
|
-
let frameSize = 0;
|
|
2360
|
-
const offset = packet.length - indexSize + 1;
|
|
2361
|
-
for (let i = 0; i < bytesPerFrameSize; i++) {
|
|
2362
|
-
if (!packet[offset + i]) return null;
|
|
2363
|
-
frameSize |= packet[offset + i] << 8 * i;
|
|
2364
|
-
}
|
|
2365
|
-
packet = packet.subarray(0, frameSize);
|
|
2366
|
-
}
|
|
2367
2379
|
const bitstream = new Bitstream(packet);
|
|
2368
2380
|
const frameMarker = bitstream.readBits(2);
|
|
2369
2381
|
if (frameMarker !== 2) {
|
|
@@ -2437,13 +2449,12 @@ var Mediabunny = (() => {
|
|
|
2437
2449
|
matrixCoefficients
|
|
2438
2450
|
};
|
|
2439
2451
|
};
|
|
2440
|
-
|
|
2452
|
+
function* iterateAv1PacketObus(packet) {
|
|
2441
2453
|
const bitstream = new Bitstream(packet);
|
|
2442
2454
|
const readLeb128 = () => {
|
|
2443
2455
|
let value = 0;
|
|
2444
2456
|
for (let i = 0; i < 8; i++) {
|
|
2445
2457
|
const byte = bitstream.readAlignedByte();
|
|
2446
|
-
if (byte === void 0) return 0;
|
|
2447
2458
|
value |= (byte & 127) << i * 7;
|
|
2448
2459
|
if (!(byte & 128)) {
|
|
2449
2460
|
break;
|
|
@@ -2458,121 +2469,133 @@ var Mediabunny = (() => {
|
|
|
2458
2469
|
return value;
|
|
2459
2470
|
};
|
|
2460
2471
|
while (bitstream.getBitsLeft() >= 8) {
|
|
2461
|
-
|
|
2462
|
-
const obuType =
|
|
2463
|
-
const obuExtension =
|
|
2464
|
-
const obuHasSizeField =
|
|
2472
|
+
bitstream.skipBits(1);
|
|
2473
|
+
const obuType = bitstream.readBits(4);
|
|
2474
|
+
const obuExtension = bitstream.readBits(1);
|
|
2475
|
+
const obuHasSizeField = bitstream.readBits(1);
|
|
2476
|
+
bitstream.skipBits(1);
|
|
2465
2477
|
if (obuExtension) {
|
|
2466
2478
|
bitstream.skipBits(8);
|
|
2467
2479
|
}
|
|
2468
2480
|
let obuSize;
|
|
2469
2481
|
if (obuHasSizeField) {
|
|
2470
2482
|
const obuSizeValue = readLeb128();
|
|
2471
|
-
if (obuSizeValue === null) return
|
|
2483
|
+
if (obuSizeValue === null) return;
|
|
2472
2484
|
obuSize = obuSizeValue;
|
|
2473
2485
|
} else {
|
|
2474
2486
|
obuSize = Math.floor(bitstream.getBitsLeft() / 8);
|
|
2475
2487
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2488
|
+
assert(bitstream.pos % 8 === 0);
|
|
2489
|
+
yield {
|
|
2490
|
+
type: obuType,
|
|
2491
|
+
data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize)
|
|
2492
|
+
};
|
|
2493
|
+
bitstream.skipBits(obuSize * 8);
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
var extractAv1CodecInfoFromPacket = (packet) => {
|
|
2497
|
+
for (const { type, data } of iterateAv1PacketObus(packet)) {
|
|
2498
|
+
if (type !== 1) {
|
|
2499
|
+
continue;
|
|
2500
|
+
}
|
|
2501
|
+
const bitstream = new Bitstream(data);
|
|
2502
|
+
const seqProfile = bitstream.readBits(3);
|
|
2503
|
+
const stillPicture = bitstream.readBits(1);
|
|
2504
|
+
const reducedStillPictureHeader = bitstream.readBits(1);
|
|
2505
|
+
let seqLevel = 0;
|
|
2506
|
+
let seqTier = 0;
|
|
2507
|
+
let bufferDelayLengthMinus1 = 0;
|
|
2508
|
+
if (reducedStillPictureHeader) {
|
|
2509
|
+
seqLevel = bitstream.readBits(5);
|
|
2510
|
+
} else {
|
|
2511
|
+
const timingInfoPresentFlag = bitstream.readBits(1);
|
|
2512
|
+
if (timingInfoPresentFlag) {
|
|
2513
|
+
bitstream.skipBits(32);
|
|
2514
|
+
bitstream.skipBits(32);
|
|
2515
|
+
const equalPictureInterval = bitstream.readBits(1);
|
|
2516
|
+
if (equalPictureInterval) {
|
|
2517
|
+
return null;
|
|
2494
2518
|
}
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2519
|
+
}
|
|
2520
|
+
const decoderModelInfoPresentFlag = bitstream.readBits(1);
|
|
2521
|
+
if (decoderModelInfoPresentFlag) {
|
|
2522
|
+
bufferDelayLengthMinus1 = bitstream.readBits(5);
|
|
2523
|
+
bitstream.skipBits(32);
|
|
2524
|
+
bitstream.skipBits(5);
|
|
2525
|
+
bitstream.skipBits(5);
|
|
2526
|
+
}
|
|
2527
|
+
const operatingPointsCntMinus1 = bitstream.readBits(5);
|
|
2528
|
+
for (let i = 0; i <= operatingPointsCntMinus1; i++) {
|
|
2529
|
+
bitstream.skipBits(12);
|
|
2530
|
+
const seqLevelIdx = bitstream.readBits(5);
|
|
2531
|
+
if (i === 0) {
|
|
2532
|
+
seqLevel = seqLevelIdx;
|
|
2501
2533
|
}
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
bitstream.skipBits(12);
|
|
2505
|
-
const seqLevelIdx = bitstream.readBits(5);
|
|
2534
|
+
if (seqLevelIdx > 7) {
|
|
2535
|
+
const seqTierTemp = bitstream.readBits(1);
|
|
2506
2536
|
if (i === 0) {
|
|
2507
|
-
|
|
2508
|
-
}
|
|
2509
|
-
if (seqLevelIdx > 7) {
|
|
2510
|
-
const seqTierTemp = bitstream.readBits(1);
|
|
2511
|
-
if (i === 0) {
|
|
2512
|
-
seqTier = seqTierTemp;
|
|
2513
|
-
}
|
|
2537
|
+
seqTier = seqTierTemp;
|
|
2514
2538
|
}
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
}
|
|
2524
|
-
const initialDisplayDelayPresentFlag = bitstream.readBits(1);
|
|
2525
|
-
if (initialDisplayDelayPresentFlag) {
|
|
2526
|
-
bitstream.skipBits(4);
|
|
2539
|
+
}
|
|
2540
|
+
if (decoderModelInfoPresentFlag) {
|
|
2541
|
+
const decoderModelPresentForThisOp = bitstream.readBits(1);
|
|
2542
|
+
if (decoderModelPresentForThisOp) {
|
|
2543
|
+
const n = bufferDelayLengthMinus1 + 1;
|
|
2544
|
+
bitstream.skipBits(n);
|
|
2545
|
+
bitstream.skipBits(n);
|
|
2546
|
+
bitstream.skipBits(1);
|
|
2527
2547
|
}
|
|
2528
2548
|
}
|
|
2549
|
+
const initialDisplayDelayPresentFlag = bitstream.readBits(1);
|
|
2550
|
+
if (initialDisplayDelayPresentFlag) {
|
|
2551
|
+
bitstream.skipBits(4);
|
|
2552
|
+
}
|
|
2529
2553
|
}
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2554
|
+
}
|
|
2555
|
+
const highBitdepth = bitstream.readBits(1);
|
|
2556
|
+
let bitDepth = 8;
|
|
2557
|
+
if (seqProfile === 2 && highBitdepth) {
|
|
2558
|
+
const twelveBit = bitstream.readBits(1);
|
|
2559
|
+
bitDepth = twelveBit ? 12 : 10;
|
|
2560
|
+
} else if (seqProfile <= 2) {
|
|
2561
|
+
bitDepth = highBitdepth ? 10 : 8;
|
|
2562
|
+
}
|
|
2563
|
+
let monochrome = 0;
|
|
2564
|
+
if (seqProfile !== 1) {
|
|
2565
|
+
monochrome = bitstream.readBits(1);
|
|
2566
|
+
}
|
|
2567
|
+
let chromaSubsamplingX = 1;
|
|
2568
|
+
let chromaSubsamplingY = 1;
|
|
2569
|
+
let chromaSamplePosition = 0;
|
|
2570
|
+
if (!monochrome) {
|
|
2571
|
+
if (seqProfile === 0) {
|
|
2572
|
+
chromaSubsamplingX = 1;
|
|
2573
|
+
chromaSubsamplingY = 1;
|
|
2574
|
+
} else if (seqProfile === 1) {
|
|
2575
|
+
chromaSubsamplingX = 0;
|
|
2576
|
+
chromaSubsamplingY = 0;
|
|
2577
|
+
} else {
|
|
2578
|
+
if (bitDepth === 12) {
|
|
2579
|
+
chromaSubsamplingX = bitstream.readBits(1);
|
|
2580
|
+
if (chromaSubsamplingX) {
|
|
2581
|
+
chromaSubsamplingY = bitstream.readBits(1);
|
|
2558
2582
|
}
|
|
2559
2583
|
}
|
|
2560
|
-
if (chromaSubsamplingX && chromaSubsamplingY) {
|
|
2561
|
-
chromaSamplePosition = bitstream.readBits(2);
|
|
2562
|
-
}
|
|
2563
2584
|
}
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
tier: seqTier,
|
|
2568
|
-
bitDepth,
|
|
2569
|
-
monochrome,
|
|
2570
|
-
chromaSubsamplingX,
|
|
2571
|
-
chromaSubsamplingY,
|
|
2572
|
-
chromaSamplePosition
|
|
2573
|
-
};
|
|
2585
|
+
if (chromaSubsamplingX && chromaSubsamplingY) {
|
|
2586
|
+
chromaSamplePosition = bitstream.readBits(2);
|
|
2587
|
+
}
|
|
2574
2588
|
}
|
|
2575
|
-
|
|
2589
|
+
return {
|
|
2590
|
+
profile: seqProfile,
|
|
2591
|
+
level: seqLevel,
|
|
2592
|
+
tier: seqTier,
|
|
2593
|
+
bitDepth,
|
|
2594
|
+
monochrome,
|
|
2595
|
+
chromaSubsamplingX,
|
|
2596
|
+
chromaSubsamplingY,
|
|
2597
|
+
chromaSamplePosition
|
|
2598
|
+
};
|
|
2576
2599
|
}
|
|
2577
2600
|
return null;
|
|
2578
2601
|
};
|
|
@@ -2703,6 +2726,105 @@ var Mediabunny = (() => {
|
|
|
2703
2726
|
}
|
|
2704
2727
|
return { modeBlockflags };
|
|
2705
2728
|
};
|
|
2729
|
+
var determineVideoPacketType = async (videoTrack, packet) => {
|
|
2730
|
+
assert(videoTrack.codec);
|
|
2731
|
+
switch (videoTrack.codec) {
|
|
2732
|
+
case "avc":
|
|
2733
|
+
{
|
|
2734
|
+
const decoderConfig = await videoTrack.getDecoderConfig();
|
|
2735
|
+
assert(decoderConfig);
|
|
2736
|
+
let nalUnits;
|
|
2737
|
+
if (decoderConfig.description) {
|
|
2738
|
+
const bytes2 = toUint8Array(decoderConfig.description);
|
|
2739
|
+
const lengthSizeMinusOne = bytes2[4] & 3;
|
|
2740
|
+
const lengthSize = lengthSizeMinusOne + 1;
|
|
2741
|
+
nalUnits = findNalUnitsInLengthPrefixed(packet.data, lengthSize);
|
|
2742
|
+
} else {
|
|
2743
|
+
nalUnits = findNalUnitsInAnnexB(packet.data);
|
|
2744
|
+
}
|
|
2745
|
+
const isKeyframe = nalUnits.some((x) => extractNalUnitTypeForAvc(x) === 5);
|
|
2746
|
+
return isKeyframe ? "key" : "delta";
|
|
2747
|
+
}
|
|
2748
|
+
;
|
|
2749
|
+
case "hevc":
|
|
2750
|
+
{
|
|
2751
|
+
const decoderConfig = await videoTrack.getDecoderConfig();
|
|
2752
|
+
assert(decoderConfig);
|
|
2753
|
+
let nalUnits;
|
|
2754
|
+
if (decoderConfig.description) {
|
|
2755
|
+
const bytes2 = toUint8Array(decoderConfig.description);
|
|
2756
|
+
const lengthSizeMinusOne = bytes2[21] & 3;
|
|
2757
|
+
const lengthSize = lengthSizeMinusOne + 1;
|
|
2758
|
+
nalUnits = findNalUnitsInLengthPrefixed(packet.data, lengthSize);
|
|
2759
|
+
} else {
|
|
2760
|
+
nalUnits = findNalUnitsInAnnexB(packet.data);
|
|
2761
|
+
}
|
|
2762
|
+
const isKeyframe = nalUnits.some((x) => {
|
|
2763
|
+
const type = extractNalUnitTypeForHevc(x);
|
|
2764
|
+
return 16 <= type && type <= 23;
|
|
2765
|
+
});
|
|
2766
|
+
return isKeyframe ? "key" : "delta";
|
|
2767
|
+
}
|
|
2768
|
+
;
|
|
2769
|
+
case "vp8":
|
|
2770
|
+
{
|
|
2771
|
+
const frameType = packet.data[0] & 1;
|
|
2772
|
+
return frameType === 0 ? "key" : "delta";
|
|
2773
|
+
}
|
|
2774
|
+
;
|
|
2775
|
+
case "vp9":
|
|
2776
|
+
{
|
|
2777
|
+
const bitstream = new Bitstream(packet.data);
|
|
2778
|
+
if (bitstream.readBits(2) !== 2) {
|
|
2779
|
+
return null;
|
|
2780
|
+
}
|
|
2781
|
+
;
|
|
2782
|
+
const profileLowBit = bitstream.readBits(1);
|
|
2783
|
+
const profileHighBit = bitstream.readBits(1);
|
|
2784
|
+
const profile = (profileHighBit << 1) + profileLowBit;
|
|
2785
|
+
if (profile === 3) {
|
|
2786
|
+
bitstream.skipBits(1);
|
|
2787
|
+
}
|
|
2788
|
+
const showExistingFrame = bitstream.readBits(1);
|
|
2789
|
+
if (showExistingFrame) {
|
|
2790
|
+
return null;
|
|
2791
|
+
}
|
|
2792
|
+
const frameType = bitstream.readBits(1);
|
|
2793
|
+
return frameType === 0 ? "key" : "delta";
|
|
2794
|
+
}
|
|
2795
|
+
;
|
|
2796
|
+
case "av1":
|
|
2797
|
+
{
|
|
2798
|
+
let reducedStillPictureHeader = false;
|
|
2799
|
+
for (const { type, data } of iterateAv1PacketObus(packet.data)) {
|
|
2800
|
+
if (type === 1) {
|
|
2801
|
+
const bitstream = new Bitstream(data);
|
|
2802
|
+
bitstream.skipBits(4);
|
|
2803
|
+
reducedStillPictureHeader = !!bitstream.readBits(1);
|
|
2804
|
+
} else if (type === 3 || type === 6 || type === 7) {
|
|
2805
|
+
if (reducedStillPictureHeader) {
|
|
2806
|
+
return "key";
|
|
2807
|
+
}
|
|
2808
|
+
const bitstream = new Bitstream(data);
|
|
2809
|
+
const showExistingFrame = bitstream.readBits(1);
|
|
2810
|
+
if (showExistingFrame) {
|
|
2811
|
+
return null;
|
|
2812
|
+
}
|
|
2813
|
+
const frameType = bitstream.readBits(2);
|
|
2814
|
+
return frameType === 0 ? "key" : "delta";
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
return null;
|
|
2818
|
+
}
|
|
2819
|
+
;
|
|
2820
|
+
default:
|
|
2821
|
+
{
|
|
2822
|
+
assertNever(videoTrack.codec);
|
|
2823
|
+
assert(false);
|
|
2824
|
+
}
|
|
2825
|
+
;
|
|
2826
|
+
}
|
|
2827
|
+
};
|
|
2706
2828
|
|
|
2707
2829
|
// src/isobmff/isobmff-boxes.ts
|
|
2708
2830
|
var IsobmffBoxWriter = class {
|
|
@@ -5970,7 +6092,7 @@ ${cue.notes ?? ""}`;
|
|
|
5970
6092
|
if (chunk.type !== "key") return;
|
|
5971
6093
|
if (!trackData.info.decoderConfig.colorSpace || !trackData.info.decoderConfig.colorSpace.matrix) return;
|
|
5972
6094
|
const bitstream = new Bitstream(chunk.data);
|
|
5973
|
-
|
|
6095
|
+
bitstream.skipBits(2);
|
|
5974
6096
|
const profileLowBit = bitstream.readBits(1);
|
|
5975
6097
|
const profileHighBit = bitstream.readBits(1);
|
|
5976
6098
|
const profile = (profileHighBit << 1) + profileLowBit;
|
|
@@ -7933,12 +8055,34 @@ ${cue.notes ?? ""}`;
|
|
|
7933
8055
|
if (options.metadataOnly !== void 0 && typeof options.metadataOnly !== "boolean") {
|
|
7934
8056
|
throw new TypeError("options.metadataOnly, when defined, must be a boolean.");
|
|
7935
8057
|
}
|
|
8058
|
+
if (options.verifyKeyPackets !== void 0 && typeof options.verifyKeyPackets !== "boolean") {
|
|
8059
|
+
throw new TypeError("options.verifyKeyPackets, when defined, must be a boolean.");
|
|
8060
|
+
}
|
|
8061
|
+
if (options.verifyKeyPackets && options.metadataOnly) {
|
|
8062
|
+
throw new TypeError("options.verifyKeyPackets and options.metadataOnly cannot be enabled together.");
|
|
8063
|
+
}
|
|
7936
8064
|
};
|
|
7937
8065
|
var validateTimestamp = (timestamp) => {
|
|
7938
8066
|
if (typeof timestamp !== "number" || Number.isNaN(timestamp)) {
|
|
7939
8067
|
throw new TypeError("timestamp must be a number.");
|
|
7940
8068
|
}
|
|
7941
8069
|
};
|
|
8070
|
+
var maybeFixPacketType = (track, promise, options) => {
|
|
8071
|
+
if (options.verifyKeyPackets) {
|
|
8072
|
+
return promise.then(async (packet) => {
|
|
8073
|
+
if (!packet || packet.type === "delta") {
|
|
8074
|
+
return packet;
|
|
8075
|
+
}
|
|
8076
|
+
const determinedType = await track.determinePacketType(packet);
|
|
8077
|
+
if (determinedType) {
|
|
8078
|
+
packet.type = determinedType;
|
|
8079
|
+
}
|
|
8080
|
+
return packet;
|
|
8081
|
+
});
|
|
8082
|
+
} else {
|
|
8083
|
+
return promise;
|
|
8084
|
+
}
|
|
8085
|
+
};
|
|
7942
8086
|
var EncodedPacketSink = class {
|
|
7943
8087
|
constructor(track) {
|
|
7944
8088
|
if (!(track instanceof InputTrack)) {
|
|
@@ -7952,7 +8096,7 @@ ${cue.notes ?? ""}`;
|
|
|
7952
8096
|
*/
|
|
7953
8097
|
getFirstPacket(options = {}) {
|
|
7954
8098
|
validatePacketRetrievalOptions(options);
|
|
7955
|
-
return this._track._backing.getFirstPacket(options);
|
|
8099
|
+
return maybeFixPacketType(this._track, this._track._backing.getFirstPacket(options), options);
|
|
7956
8100
|
}
|
|
7957
8101
|
/**
|
|
7958
8102
|
* Retrieves the packet corresponding to the given timestamp, in seconds. More specifically, returns the last packet
|
|
@@ -7965,7 +8109,7 @@ ${cue.notes ?? ""}`;
|
|
|
7965
8109
|
getPacket(timestamp, options = {}) {
|
|
7966
8110
|
validateTimestamp(timestamp);
|
|
7967
8111
|
validatePacketRetrievalOptions(options);
|
|
7968
|
-
return this._track._backing.getPacket(timestamp, options);
|
|
8112
|
+
return maybeFixPacketType(this._track, this._track._backing.getPacket(timestamp, options), options);
|
|
7969
8113
|
}
|
|
7970
8114
|
/**
|
|
7971
8115
|
* Retrieves the packet following the given packet (in decode order), or null if the given packet is the
|
|
@@ -7976,7 +8120,7 @@ ${cue.notes ?? ""}`;
|
|
|
7976
8120
|
throw new TypeError("packet must be an EncodedPacket.");
|
|
7977
8121
|
}
|
|
7978
8122
|
validatePacketRetrievalOptions(options);
|
|
7979
|
-
return this._track._backing.getNextPacket(packet, options);
|
|
8123
|
+
return maybeFixPacketType(this._track, this._track._backing.getNextPacket(packet, options), options);
|
|
7980
8124
|
}
|
|
7981
8125
|
/**
|
|
7982
8126
|
* Retrieves the key packet corresponding to the given timestamp, in seconds. More specifically, returns the last
|
|
@@ -7985,23 +8129,49 @@ ${cue.notes ?? ""}`;
|
|
|
7985
8129
|
* last key packet using `getKeyPacket(Infinity)`. The method returns null if the timestamp is before the first
|
|
7986
8130
|
* key packet in the track.
|
|
7987
8131
|
*
|
|
8132
|
+
* To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
|
|
8133
|
+
*
|
|
7988
8134
|
* @param timestamp - The timestamp used for retrieval, in seconds.
|
|
7989
8135
|
*/
|
|
7990
|
-
getKeyPacket(timestamp, options = {}) {
|
|
8136
|
+
async getKeyPacket(timestamp, options = {}) {
|
|
7991
8137
|
validateTimestamp(timestamp);
|
|
7992
8138
|
validatePacketRetrievalOptions(options);
|
|
7993
|
-
|
|
8139
|
+
if (!options.verifyKeyPackets) {
|
|
8140
|
+
return this._track._backing.getKeyPacket(timestamp, options);
|
|
8141
|
+
}
|
|
8142
|
+
const packet = await this._track._backing.getKeyPacket(timestamp, options);
|
|
8143
|
+
if (!packet || packet.type === "delta") {
|
|
8144
|
+
return packet;
|
|
8145
|
+
}
|
|
8146
|
+
const determinedType = await this._track.determinePacketType(packet);
|
|
8147
|
+
if (determinedType === "delta") {
|
|
8148
|
+
return this.getKeyPacket(packet.timestamp - 1 / this._track.timeResolution, options);
|
|
8149
|
+
}
|
|
8150
|
+
return packet;
|
|
7994
8151
|
}
|
|
7995
8152
|
/**
|
|
7996
8153
|
* Retrieves the key packet following the given packet (in decode order), or null if the given packet is the last
|
|
7997
8154
|
* key packet.
|
|
8155
|
+
*
|
|
8156
|
+
* To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
|
|
7998
8157
|
*/
|
|
7999
|
-
getNextKeyPacket(packet, options = {}) {
|
|
8158
|
+
async getNextKeyPacket(packet, options = {}) {
|
|
8000
8159
|
if (!(packet instanceof EncodedPacket)) {
|
|
8001
8160
|
throw new TypeError("packet must be an EncodedPacket.");
|
|
8002
8161
|
}
|
|
8003
8162
|
validatePacketRetrievalOptions(options);
|
|
8004
|
-
|
|
8163
|
+
if (!options.verifyKeyPackets) {
|
|
8164
|
+
return this._track._backing.getNextKeyPacket(packet, options);
|
|
8165
|
+
}
|
|
8166
|
+
const nextPacket = await this._track._backing.getNextKeyPacket(packet, options);
|
|
8167
|
+
if (!nextPacket || nextPacket.type === "delta") {
|
|
8168
|
+
return nextPacket;
|
|
8169
|
+
}
|
|
8170
|
+
const determinedType = await this._track.determinePacketType(nextPacket);
|
|
8171
|
+
if (determinedType === "delta") {
|
|
8172
|
+
return this.getNextKeyPacket(nextPacket, options);
|
|
8173
|
+
}
|
|
8174
|
+
return nextPacket;
|
|
8005
8175
|
}
|
|
8006
8176
|
/**
|
|
8007
8177
|
* Creates an async iterator that yields the packets in this track in decode order. To enable fast iteration, this
|
|
@@ -8147,7 +8317,7 @@ ${cue.notes ?? ""}`;
|
|
|
8147
8317
|
}
|
|
8148
8318
|
});
|
|
8149
8319
|
const packetSink = this._createPacketSink();
|
|
8150
|
-
const keyPacket = await packetSink.getKeyPacket(startTimestamp) ?? await packetSink.getFirstPacket();
|
|
8320
|
+
const keyPacket = await packetSink.getKeyPacket(startTimestamp, { verifyKeyPackets: true }) ?? await packetSink.getFirstPacket();
|
|
8151
8321
|
if (!keyPacket) {
|
|
8152
8322
|
return;
|
|
8153
8323
|
}
|
|
@@ -8155,7 +8325,7 @@ ${cue.notes ?? ""}`;
|
|
|
8155
8325
|
let endPacket = void 0;
|
|
8156
8326
|
if (endTimestamp < Infinity) {
|
|
8157
8327
|
const packet = await packetSink.getPacket(endTimestamp);
|
|
8158
|
-
const keyPacket2 = !packet ? null : packet.type === "key" && packet.timestamp === endTimestamp ? packet : await packetSink.getNextKeyPacket(packet);
|
|
8328
|
+
const keyPacket2 = !packet ? null : packet.type === "key" && packet.timestamp === endTimestamp ? packet : await packetSink.getNextKeyPacket(packet, { verifyKeyPackets: true });
|
|
8159
8329
|
if (keyPacket2) {
|
|
8160
8330
|
endPacket = keyPacket2;
|
|
8161
8331
|
}
|
|
@@ -8307,7 +8477,7 @@ ${cue.notes ?? ""}`;
|
|
|
8307
8477
|
break;
|
|
8308
8478
|
}
|
|
8309
8479
|
const targetPacket = await packetSink.getPacket(timestamp);
|
|
8310
|
-
const keyPacket = targetPacket && await packetSink.getKeyPacket(timestamp);
|
|
8480
|
+
const keyPacket = targetPacket && await packetSink.getKeyPacket(timestamp, { verifyKeyPackets: true });
|
|
8311
8481
|
if (!keyPacket) {
|
|
8312
8482
|
if (maxSequenceNumber !== -1) {
|
|
8313
8483
|
await decodePackets();
|
|
@@ -9158,7 +9328,10 @@ ${cue.notes ?? ""}`;
|
|
|
9158
9328
|
const colorSpace = await this._backing.getColorSpace();
|
|
9159
9329
|
return colorSpace.primaries === "bt2020" || colorSpace.primaries === "smpte432" || colorSpace.transfer === "pg" || colorSpace.transfer === "hlg" || colorSpace.matrix === "bt2020-ncl";
|
|
9160
9330
|
}
|
|
9161
|
-
/**
|
|
9331
|
+
/**
|
|
9332
|
+
* Returns the decoder configuration for decoding the track's packets using a VideoDecoder. Returns null if the
|
|
9333
|
+
* track's codec is unknown.
|
|
9334
|
+
*/
|
|
9162
9335
|
getDecoderConfig() {
|
|
9163
9336
|
return this._backing.getDecoderConfig();
|
|
9164
9337
|
}
|
|
@@ -9187,6 +9360,18 @@ ${cue.notes ?? ""}`;
|
|
|
9187
9360
|
return false;
|
|
9188
9361
|
}
|
|
9189
9362
|
}
|
|
9363
|
+
async determinePacketType(packet) {
|
|
9364
|
+
if (!(packet instanceof EncodedPacket)) {
|
|
9365
|
+
throw new TypeError("packet must be an EncodedPacket.");
|
|
9366
|
+
}
|
|
9367
|
+
if (packet.isMetadataOnly) {
|
|
9368
|
+
throw new TypeError("packet must not be metadata-only to determine its type.");
|
|
9369
|
+
}
|
|
9370
|
+
if (this.codec === null) {
|
|
9371
|
+
return null;
|
|
9372
|
+
}
|
|
9373
|
+
return determineVideoPacketType(this, packet);
|
|
9374
|
+
}
|
|
9190
9375
|
};
|
|
9191
9376
|
var InputAudioTrack = class extends InputTrack {
|
|
9192
9377
|
/** @internal */
|
|
@@ -9208,7 +9393,10 @@ ${cue.notes ?? ""}`;
|
|
|
9208
9393
|
get sampleRate() {
|
|
9209
9394
|
return this._backing.getSampleRate();
|
|
9210
9395
|
}
|
|
9211
|
-
/**
|
|
9396
|
+
/**
|
|
9397
|
+
* Returns the decoder configuration for decoding the track's packets using an AudioDecoder. Returns null if the
|
|
9398
|
+
* track's codec is unknown.
|
|
9399
|
+
*/
|
|
9212
9400
|
getDecoderConfig() {
|
|
9213
9401
|
return this._backing.getDecoderConfig();
|
|
9214
9402
|
}
|
|
@@ -9241,6 +9429,15 @@ ${cue.notes ?? ""}`;
|
|
|
9241
9429
|
return false;
|
|
9242
9430
|
}
|
|
9243
9431
|
}
|
|
9432
|
+
async determinePacketType(packet) {
|
|
9433
|
+
if (!(packet instanceof EncodedPacket)) {
|
|
9434
|
+
throw new TypeError("packet must be an EncodedPacket.");
|
|
9435
|
+
}
|
|
9436
|
+
if (this.codec === null) {
|
|
9437
|
+
return null;
|
|
9438
|
+
}
|
|
9439
|
+
return "key";
|
|
9440
|
+
}
|
|
9244
9441
|
};
|
|
9245
9442
|
|
|
9246
9443
|
// src/reader.ts
|
|
@@ -9411,6 +9608,18 @@ ${cue.notes ?? ""}`;
|
|
|
9411
9608
|
this.pos += 4;
|
|
9412
9609
|
return view2.getUint32(offset, this.littleEndian);
|
|
9413
9610
|
}
|
|
9611
|
+
readU64() {
|
|
9612
|
+
let low;
|
|
9613
|
+
let high;
|
|
9614
|
+
if (this.littleEndian) {
|
|
9615
|
+
low = this.readU32();
|
|
9616
|
+
high = this.readU32();
|
|
9617
|
+
} else {
|
|
9618
|
+
high = this.readU32();
|
|
9619
|
+
low = this.readU32();
|
|
9620
|
+
}
|
|
9621
|
+
return high * 4294967296 + low;
|
|
9622
|
+
}
|
|
9414
9623
|
readAscii(length) {
|
|
9415
9624
|
const { view: view2, offset } = this.reader.getViewAndOffset(this.pos, this.pos + length);
|
|
9416
9625
|
this.pos += length;
|
|
@@ -9438,25 +9647,38 @@ ${cue.notes ?? ""}`;
|
|
|
9438
9647
|
return this.metadataPromise ??= (async () => {
|
|
9439
9648
|
const actualFileSize = await this.metadataReader.reader.source.getSize();
|
|
9440
9649
|
const riffType = this.metadataReader.readAscii(4);
|
|
9441
|
-
this.metadataReader.littleEndian = riffType
|
|
9442
|
-
const
|
|
9650
|
+
this.metadataReader.littleEndian = riffType !== "RIFX";
|
|
9651
|
+
const isRf64 = riffType === "RF64";
|
|
9652
|
+
const outerChunkSize = this.metadataReader.readU32();
|
|
9653
|
+
let totalFileSize = isRf64 ? actualFileSize : Math.min(outerChunkSize + 8, actualFileSize);
|
|
9443
9654
|
const format = this.metadataReader.readAscii(4);
|
|
9444
9655
|
if (format !== "WAVE") {
|
|
9445
9656
|
throw new Error("Invalid WAVE file - wrong format");
|
|
9446
9657
|
}
|
|
9447
9658
|
this.metadataReader.pos = 12;
|
|
9659
|
+
let chunksRead = 0;
|
|
9660
|
+
let dataChunkSize = null;
|
|
9448
9661
|
while (this.metadataReader.pos < totalFileSize) {
|
|
9449
9662
|
await this.metadataReader.reader.loadRange(this.metadataReader.pos, this.metadataReader.pos + 8);
|
|
9450
9663
|
const chunkId = this.metadataReader.readAscii(4);
|
|
9451
9664
|
const chunkSize = this.metadataReader.readU32();
|
|
9452
9665
|
const startPos = this.metadataReader.pos;
|
|
9666
|
+
if (isRf64 && chunksRead === 0 && chunkId !== "ds64") {
|
|
9667
|
+
throw new Error('Invalid RF64 file: First chunk must be "ds64".');
|
|
9668
|
+
}
|
|
9453
9669
|
if (chunkId === "fmt ") {
|
|
9454
9670
|
await this.parseFmtChunk(chunkSize);
|
|
9455
9671
|
} else if (chunkId === "data") {
|
|
9672
|
+
dataChunkSize ??= chunkSize;
|
|
9456
9673
|
this.dataStart = this.metadataReader.pos;
|
|
9457
|
-
this.dataSize = Math.min(
|
|
9674
|
+
this.dataSize = Math.min(dataChunkSize, totalFileSize - this.dataStart);
|
|
9675
|
+
} else if (chunkId === "ds64") {
|
|
9676
|
+
const riffChunkSize = this.metadataReader.readU64();
|
|
9677
|
+
dataChunkSize = this.metadataReader.readU64();
|
|
9678
|
+
totalFileSize = Math.min(riffChunkSize + 8, actualFileSize);
|
|
9458
9679
|
}
|
|
9459
9680
|
this.metadataReader.pos = startPos + chunkSize + (chunkSize & 1);
|
|
9681
|
+
chunksRead++;
|
|
9460
9682
|
}
|
|
9461
9683
|
if (!this.audioInfo) {
|
|
9462
9684
|
throw new Error('Invalid WAVE file - missing "fmt " chunk');
|
|
@@ -9651,13 +9873,18 @@ ${cue.notes ?? ""}`;
|
|
|
9651
9873
|
this.helper = new Uint8Array(8);
|
|
9652
9874
|
this.helperView = new DataView(this.helper.buffer);
|
|
9653
9875
|
}
|
|
9876
|
+
writeU16(value) {
|
|
9877
|
+
this.helperView.setUint16(0, value, true);
|
|
9878
|
+
this.writer.write(this.helper.subarray(0, 2));
|
|
9879
|
+
}
|
|
9654
9880
|
writeU32(value) {
|
|
9655
9881
|
this.helperView.setUint32(0, value, true);
|
|
9656
9882
|
this.writer.write(this.helper.subarray(0, 4));
|
|
9657
9883
|
}
|
|
9658
|
-
|
|
9659
|
-
this.helperView.
|
|
9660
|
-
this.
|
|
9884
|
+
writeU64(value) {
|
|
9885
|
+
this.helperView.setUint32(0, value, true);
|
|
9886
|
+
this.helperView.setUint32(4, Math.floor(value / 2 ** 32), true);
|
|
9887
|
+
this.writer.write(this.helper);
|
|
9661
9888
|
}
|
|
9662
9889
|
writeAscii(text) {
|
|
9663
9890
|
this.writer.write(new TextEncoder().encode(text));
|
|
@@ -9670,9 +9897,12 @@ ${cue.notes ?? ""}`;
|
|
|
9670
9897
|
super(output);
|
|
9671
9898
|
this.headerWritten = false;
|
|
9672
9899
|
this.dataSize = 0;
|
|
9900
|
+
this.sampleRate = null;
|
|
9901
|
+
this.sampleCount = 0;
|
|
9673
9902
|
this.format = format;
|
|
9674
9903
|
this.writer = output._writer;
|
|
9675
9904
|
this.riffWriter = new RiffWriter(output._writer);
|
|
9905
|
+
this.isRf64 = !!format._options.large;
|
|
9676
9906
|
}
|
|
9677
9907
|
async start() {
|
|
9678
9908
|
}
|
|
@@ -9690,11 +9920,18 @@ ${cue.notes ?? ""}`;
|
|
|
9690
9920
|
assert(meta);
|
|
9691
9921
|
assert(meta.decoderConfig);
|
|
9692
9922
|
this.writeHeader(track, meta.decoderConfig);
|
|
9923
|
+
this.sampleRate = meta.decoderConfig.sampleRate;
|
|
9693
9924
|
this.headerWritten = true;
|
|
9694
9925
|
}
|
|
9695
9926
|
this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === "key");
|
|
9927
|
+
if (!this.isRf64 && this.writer.getPos() + packet.data.byteLength >= 2 ** 32) {
|
|
9928
|
+
throw new Error(
|
|
9929
|
+
"Adding more audio data would exceed the maximum RIFF size of 4 GiB. To write larger files, use RF64 by setting `large: true` in the WavOutputFormatOptions."
|
|
9930
|
+
);
|
|
9931
|
+
}
|
|
9696
9932
|
this.writer.write(packet.data);
|
|
9697
9933
|
this.dataSize += packet.data.byteLength;
|
|
9934
|
+
this.sampleCount += Math.round(packet.duration * this.sampleRate);
|
|
9698
9935
|
await this.writer.flush();
|
|
9699
9936
|
} finally {
|
|
9700
9937
|
release();
|
|
@@ -9722,9 +9959,21 @@ ${cue.notes ?? ""}`;
|
|
|
9722
9959
|
const channels = config.numberOfChannels;
|
|
9723
9960
|
const sampleRate = config.sampleRate;
|
|
9724
9961
|
const blockSize = pcmInfo.sampleSize * channels;
|
|
9725
|
-
this.riffWriter.writeAscii("RIFF");
|
|
9726
|
-
this.
|
|
9962
|
+
this.riffWriter.writeAscii(this.isRf64 ? "RF64" : "RIFF");
|
|
9963
|
+
if (this.isRf64) {
|
|
9964
|
+
this.riffWriter.writeU32(4294967295);
|
|
9965
|
+
} else {
|
|
9966
|
+
this.riffWriter.writeU32(0);
|
|
9967
|
+
}
|
|
9727
9968
|
this.riffWriter.writeAscii("WAVE");
|
|
9969
|
+
if (this.isRf64) {
|
|
9970
|
+
this.riffWriter.writeAscii("ds64");
|
|
9971
|
+
this.riffWriter.writeU32(28);
|
|
9972
|
+
this.riffWriter.writeU64(0);
|
|
9973
|
+
this.riffWriter.writeU64(0);
|
|
9974
|
+
this.riffWriter.writeU64(0);
|
|
9975
|
+
this.riffWriter.writeU32(0);
|
|
9976
|
+
}
|
|
9728
9977
|
this.riffWriter.writeAscii("fmt ");
|
|
9729
9978
|
this.riffWriter.writeU32(16);
|
|
9730
9979
|
this.riffWriter.writeU16(format);
|
|
@@ -9734,7 +9983,11 @@ ${cue.notes ?? ""}`;
|
|
|
9734
9983
|
this.riffWriter.writeU16(blockSize);
|
|
9735
9984
|
this.riffWriter.writeU16(8 * pcmInfo.sampleSize);
|
|
9736
9985
|
this.riffWriter.writeAscii("data");
|
|
9737
|
-
this.
|
|
9986
|
+
if (this.isRf64) {
|
|
9987
|
+
this.riffWriter.writeU32(4294967295);
|
|
9988
|
+
} else {
|
|
9989
|
+
this.riffWriter.writeU32(0);
|
|
9990
|
+
}
|
|
9738
9991
|
if (this.format._options.onHeader) {
|
|
9739
9992
|
const { data, start } = this.writer.stopTrackingWrites();
|
|
9740
9993
|
this.format._options.onHeader(data, start);
|
|
@@ -9743,10 +9996,19 @@ ${cue.notes ?? ""}`;
|
|
|
9743
9996
|
async finalize() {
|
|
9744
9997
|
const release = await this.mutex.acquire();
|
|
9745
9998
|
const endPos = this.writer.getPos();
|
|
9746
|
-
this.
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9999
|
+
if (this.isRf64) {
|
|
10000
|
+
this.writer.seek(20);
|
|
10001
|
+
this.riffWriter.writeU64(endPos - 8);
|
|
10002
|
+
this.writer.seek(28);
|
|
10003
|
+
this.riffWriter.writeU64(this.dataSize);
|
|
10004
|
+
this.writer.seek(36);
|
|
10005
|
+
this.riffWriter.writeU64(this.sampleCount);
|
|
10006
|
+
} else {
|
|
10007
|
+
this.writer.seek(4);
|
|
10008
|
+
this.riffWriter.writeU32(endPos - 8);
|
|
10009
|
+
this.writer.seek(40);
|
|
10010
|
+
this.riffWriter.writeU32(this.dataSize);
|
|
10011
|
+
}
|
|
9750
10012
|
this.writer.seek(endPos);
|
|
9751
10013
|
release();
|
|
9752
10014
|
}
|
|
@@ -10005,6 +10267,9 @@ ${cue.notes ?? ""}`;
|
|
|
10005
10267
|
if (!options || typeof options !== "object") {
|
|
10006
10268
|
throw new TypeError("options must be an object.");
|
|
10007
10269
|
}
|
|
10270
|
+
if (options.large !== void 0 && typeof options.large !== "boolean") {
|
|
10271
|
+
throw new TypeError("options.large, when provided, must be a boolean.");
|
|
10272
|
+
}
|
|
10008
10273
|
if (options.onHeader !== void 0 && typeof options.onHeader !== "function") {
|
|
10009
10274
|
throw new TypeError("options.onHeader, when provided, must be a function.");
|
|
10010
10275
|
}
|
|
@@ -15973,7 +16238,7 @@ ${cue.notes ?? ""}`;
|
|
|
15973
16238
|
}
|
|
15974
16239
|
const riffReader = new RiffReader(input._mainReader);
|
|
15975
16240
|
const riffType = riffReader.readAscii(4);
|
|
15976
|
-
if (riffType !== "RIFF" && riffType !== "RIFX") {
|
|
16241
|
+
if (riffType !== "RIFF" && riffType !== "RIFX" && riffType !== "RF64") {
|
|
15977
16242
|
return false;
|
|
15978
16243
|
}
|
|
15979
16244
|
riffReader.pos = 8;
|
|
@@ -16380,7 +16645,7 @@ ${cue.notes ?? ""}`;
|
|
|
16380
16645
|
const decoderConfig = await track.getDecoderConfig();
|
|
16381
16646
|
const meta = { decoderConfig: decoderConfig ?? void 0 };
|
|
16382
16647
|
const endPacket = Number.isFinite(this._endTimestamp) ? await sink.getPacket(this._endTimestamp, { metadataOnly: true }) ?? void 0 : void 0;
|
|
16383
|
-
for await (const packet of sink.packets(void 0, endPacket)) {
|
|
16648
|
+
for await (const packet of sink.packets(void 0, endPacket, { verifyKeyPackets: true })) {
|
|
16384
16649
|
if (this._synchronizer.shouldWait(track.id, packet.timestamp)) {
|
|
16385
16650
|
await this._synchronizer.wait(packet.timestamp);
|
|
16386
16651
|
}
|