mediabunny 1.47.0 → 1.48.1
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 +193 -34
- package/dist/bundles/mediabunny.min.cjs +11 -11
- package/dist/bundles/mediabunny.min.mjs +11 -11
- package/dist/bundles/mediabunny.mjs +193 -34
- package/dist/bundles/mediabunny.node.cjs +193 -34
- package/dist/mediabunny.d.ts +72 -4
- package/dist/modules/src/adts/adts-demuxer.d.ts +1 -0
- package/dist/modules/src/adts/adts-demuxer.d.ts.map +1 -1
- package/dist/modules/src/adts/adts-demuxer.js +3 -0
- package/dist/modules/src/flac/flac-demuxer.d.ts +1 -0
- package/dist/modules/src/flac/flac-demuxer.d.ts.map +1 -1
- package/dist/modules/src/flac/flac-demuxer.js +3 -0
- package/dist/modules/src/hls/hls-demuxer.d.ts.map +1 -1
- package/dist/modules/src/hls/hls-demuxer.js +6 -1
- package/dist/modules/src/hls/hls-segmented-input.d.ts +1 -0
- package/dist/modules/src/hls/hls-segmented-input.d.ts.map +1 -1
- package/dist/modules/src/hls/hls-segmented-input.js +28 -11
- package/dist/modules/src/index.d.ts +2 -2
- package/dist/modules/src/index.d.ts.map +1 -1
- package/dist/modules/src/input-format.d.ts +21 -0
- package/dist/modules/src/input-format.d.ts.map +1 -1
- package/dist/modules/src/input-format.js +9 -0
- package/dist/modules/src/input-track.d.ts +17 -0
- package/dist/modules/src/input-track.d.ts.map +1 -1
- package/dist/modules/src/input-track.js +20 -0
- package/dist/modules/src/isobmff/isobmff-demuxer.js +3 -0
- package/dist/modules/src/matroska/matroska-demuxer.js +3 -0
- package/dist/modules/src/media-sink.d.ts +20 -1
- package/dist/modules/src/media-sink.d.ts.map +1 -1
- package/dist/modules/src/media-sink.js +26 -3
- package/dist/modules/src/mp3/mp3-demuxer.d.ts +1 -0
- package/dist/modules/src/mp3/mp3-demuxer.d.ts.map +1 -1
- package/dist/modules/src/mp3/mp3-demuxer.js +3 -0
- package/dist/modules/src/mpeg-ts/mpeg-ts-demuxer.d.ts.map +1 -1
- package/dist/modules/src/mpeg-ts/mpeg-ts-demuxer.js +91 -29
- package/dist/modules/src/ogg/ogg-demuxer.d.ts +1 -0
- package/dist/modules/src/ogg/ogg-demuxer.d.ts.map +1 -1
- package/dist/modules/src/ogg/ogg-demuxer.js +3 -0
- package/dist/modules/src/segmented-input.d.ts +7 -1
- package/dist/modules/src/segmented-input.d.ts.map +1 -1
- package/dist/modules/src/segmented-input.js +13 -1
- package/dist/modules/src/source.d.ts +13 -3
- package/dist/modules/src/source.d.ts.map +1 -1
- package/dist/modules/src/source.js +19 -3
- package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
- package/dist/modules/src/wave/wave-demuxer.d.ts +1 -0
- package/dist/modules/src/wave/wave-demuxer.d.ts.map +1 -1
- package/dist/modules/src/wave/wave-demuxer.js +3 -0
- package/package.json +1 -1
- package/src/adts/adts-demuxer.ts +4 -0
- package/src/flac/flac-demuxer.ts +4 -0
- package/src/hls/hls-demuxer.ts +8 -1
- package/src/hls/hls-segmented-input.ts +32 -12
- package/src/index.ts +2 -0
- package/src/input-format.ts +33 -0
- package/src/input-track.ts +23 -0
- package/src/isobmff/isobmff-demuxer.ts +4 -0
- package/src/matroska/matroska-demuxer.ts +4 -0
- package/src/media-sink.ts +54 -3
- package/src/mp3/mp3-demuxer.ts +4 -0
- package/src/mpeg-ts/mpeg-ts-demuxer.ts +102 -30
- package/src/ogg/ogg-demuxer.ts +4 -0
- package/src/segmented-input.ts +23 -2
- package/src/source.ts +26 -5
- package/src/wave/wave-demuxer.ts +4 -0
|
@@ -7578,6 +7578,9 @@ var Mediabunny = (() => {
|
|
|
7578
7578
|
isRelativeToUnixEpoch() {
|
|
7579
7579
|
return false;
|
|
7580
7580
|
}
|
|
7581
|
+
getUnixTimeForTimestamp() {
|
|
7582
|
+
return null;
|
|
7583
|
+
}
|
|
7581
7584
|
getDisposition() {
|
|
7582
7585
|
return this.internalTrack.disposition;
|
|
7583
7586
|
}
|
|
@@ -10455,6 +10458,9 @@ var Mediabunny = (() => {
|
|
|
10455
10458
|
isRelativeToUnixEpoch() {
|
|
10456
10459
|
return false;
|
|
10457
10460
|
}
|
|
10461
|
+
getUnixTimeForTimestamp() {
|
|
10462
|
+
return null;
|
|
10463
|
+
}
|
|
10458
10464
|
getDisposition() {
|
|
10459
10465
|
return this.internalTrack.disposition;
|
|
10460
10466
|
}
|
|
@@ -11075,6 +11081,9 @@ var Mediabunny = (() => {
|
|
|
11075
11081
|
isRelativeToUnixEpoch() {
|
|
11076
11082
|
return false;
|
|
11077
11083
|
}
|
|
11084
|
+
getUnixTimeForTimestamp() {
|
|
11085
|
+
return null;
|
|
11086
|
+
}
|
|
11078
11087
|
getPairingMask() {
|
|
11079
11088
|
return 1n;
|
|
11080
11089
|
}
|
|
@@ -11643,6 +11652,9 @@ var Mediabunny = (() => {
|
|
|
11643
11652
|
isRelativeToUnixEpoch() {
|
|
11644
11653
|
return false;
|
|
11645
11654
|
}
|
|
11655
|
+
getUnixTimeForTimestamp() {
|
|
11656
|
+
return null;
|
|
11657
|
+
}
|
|
11646
11658
|
getPairingMask() {
|
|
11647
11659
|
return 1n;
|
|
11648
11660
|
}
|
|
@@ -12415,6 +12427,9 @@ var Mediabunny = (() => {
|
|
|
12415
12427
|
isRelativeToUnixEpoch() {
|
|
12416
12428
|
return false;
|
|
12417
12429
|
}
|
|
12430
|
+
getUnixTimeForTimestamp() {
|
|
12431
|
+
return null;
|
|
12432
|
+
}
|
|
12418
12433
|
getPairingMask() {
|
|
12419
12434
|
return 1n;
|
|
12420
12435
|
}
|
|
@@ -12713,6 +12728,9 @@ var Mediabunny = (() => {
|
|
|
12713
12728
|
isRelativeToUnixEpoch() {
|
|
12714
12729
|
return false;
|
|
12715
12730
|
}
|
|
12731
|
+
getUnixTimeForTimestamp() {
|
|
12732
|
+
return null;
|
|
12733
|
+
}
|
|
12716
12734
|
getPairingMask() {
|
|
12717
12735
|
return 1n;
|
|
12718
12736
|
}
|
|
@@ -13333,6 +13351,9 @@ var Mediabunny = (() => {
|
|
|
13333
13351
|
isRelativeToUnixEpoch() {
|
|
13334
13352
|
return false;
|
|
13335
13353
|
}
|
|
13354
|
+
getUnixTimeForTimestamp() {
|
|
13355
|
+
return null;
|
|
13356
|
+
}
|
|
13336
13357
|
getPairingMask() {
|
|
13337
13358
|
return 1n;
|
|
13338
13359
|
}
|
|
@@ -13525,6 +13546,10 @@ var Mediabunny = (() => {
|
|
|
13525
13546
|
currentPos += this.packetStride;
|
|
13526
13547
|
continue;
|
|
13527
13548
|
}
|
|
13549
|
+
if (hasProgramMap && !this.elementaryStreams.some((x) => x.pid === packetHeader.pid)) {
|
|
13550
|
+
currentPos += this.packetStride;
|
|
13551
|
+
continue;
|
|
13552
|
+
}
|
|
13528
13553
|
const section = await this.readSection(
|
|
13529
13554
|
currentPos,
|
|
13530
13555
|
true,
|
|
@@ -14201,6 +14226,9 @@ var Mediabunny = (() => {
|
|
|
14201
14226
|
isRelativeToUnixEpoch() {
|
|
14202
14227
|
return false;
|
|
14203
14228
|
}
|
|
14229
|
+
getUnixTimeForTimestamp() {
|
|
14230
|
+
return null;
|
|
14231
|
+
}
|
|
14204
14232
|
getPairingMask() {
|
|
14205
14233
|
return 1n;
|
|
14206
14234
|
}
|
|
@@ -14821,7 +14849,10 @@ var Mediabunny = (() => {
|
|
|
14821
14849
|
if (codec !== "avc" && codec !== "hevc") {
|
|
14822
14850
|
throw new Error("Unhandled.");
|
|
14823
14851
|
}
|
|
14852
|
+
const nalHeaderSize = codec === "avc" ? 1 : 2;
|
|
14824
14853
|
let packetStartPos = null;
|
|
14854
|
+
let frameStartFound = false;
|
|
14855
|
+
let lastFirstMacroblockInSlice = 0;
|
|
14825
14856
|
while (true) {
|
|
14826
14857
|
let remaining = this.ensureBuffered(CHUNK_SIZE);
|
|
14827
14858
|
if (remaining instanceof Promise) remaining = await remaining;
|
|
@@ -14839,7 +14870,7 @@ var Mediabunny = (() => {
|
|
|
14839
14870
|
}
|
|
14840
14871
|
i = zeroIndex;
|
|
14841
14872
|
const posBeforeZero = chunkStartPos + i;
|
|
14842
|
-
if (i +
|
|
14873
|
+
if (i + 3 >= length) {
|
|
14843
14874
|
this.seekTo(posBeforeZero);
|
|
14844
14875
|
break;
|
|
14845
14876
|
}
|
|
@@ -14847,32 +14878,68 @@ var Mediabunny = (() => {
|
|
|
14847
14878
|
const b2 = chunk[i + 2];
|
|
14848
14879
|
const b3 = chunk[i + 3];
|
|
14849
14880
|
let startCodeLength = 0;
|
|
14850
|
-
let nalUnitTypeByte = null;
|
|
14851
14881
|
if (b1 === 0 && b2 === 0 && b3 === 1) {
|
|
14852
14882
|
startCodeLength = 4;
|
|
14853
|
-
nalUnitTypeByte = chunk[i + 4];
|
|
14854
14883
|
} else if (b1 === 0 && b2 === 1) {
|
|
14855
14884
|
startCodeLength = 3;
|
|
14856
|
-
nalUnitTypeByte = b3;
|
|
14857
14885
|
}
|
|
14858
14886
|
if (startCodeLength === 0) {
|
|
14859
14887
|
i++;
|
|
14860
14888
|
continue;
|
|
14861
14889
|
}
|
|
14862
14890
|
const startCodePos = posBeforeZero;
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
|
|
14891
|
+
packetStartPos ??= startCodePos;
|
|
14892
|
+
const nalHeaderStart = i + startCodeLength;
|
|
14893
|
+
const payloadStart = nalHeaderStart + nalHeaderSize;
|
|
14894
|
+
const AVC_SLICE_HEADER_PEEK_SIZE = 6;
|
|
14895
|
+
const bytesNeeded = payloadStart + (codec === "avc" ? AVC_SLICE_HEADER_PEEK_SIZE : 1);
|
|
14896
|
+
if (bytesNeeded > length) {
|
|
14897
|
+
this.seekTo(posBeforeZero);
|
|
14898
|
+
break;
|
|
14867
14899
|
}
|
|
14868
|
-
|
|
14869
|
-
|
|
14870
|
-
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14900
|
+
const headerByte0 = chunk[nalHeaderStart];
|
|
14901
|
+
let nalUnitType;
|
|
14902
|
+
let isSlice;
|
|
14903
|
+
let isAccessUnitStart;
|
|
14904
|
+
if (codec === "avc") {
|
|
14905
|
+
nalUnitType = extractNalUnitTypeForAvc(headerByte0);
|
|
14906
|
+
isSlice = nalUnitType === 1 /* NON_IDR_SLICE */ || nalUnitType === 2 /* SLICE_DPA */ || nalUnitType === 5 /* IDR */;
|
|
14907
|
+
isAccessUnitStart = nalUnitType === 6 /* SEI */ || nalUnitType === 7 /* SPS */ || nalUnitType === 8 /* PPS */ || nalUnitType === 9 /* AUD */;
|
|
14908
|
+
} else {
|
|
14909
|
+
nalUnitType = extractNalUnitTypeForHevc(headerByte0);
|
|
14910
|
+
const layerId = (headerByte0 & 1) << 5 | chunk[nalHeaderStart + 1] >> 3;
|
|
14911
|
+
if (layerId > 0) {
|
|
14912
|
+
i += startCodeLength;
|
|
14913
|
+
continue;
|
|
14914
|
+
}
|
|
14915
|
+
isSlice = nalUnitType <= 9 /* RASL_R */ || nalUnitType >= 16 /* BLA_W_LP */ && nalUnitType <= 21;
|
|
14916
|
+
isAccessUnitStart = nalUnitType >= 32 /* VPS_NUT */ && nalUnitType <= 37 || nalUnitType === 39 /* PREFIX_SEI_NUT */ || nalUnitType >= 41 && nalUnitType <= 44 || nalUnitType >= 48 && nalUnitType <= 55;
|
|
14917
|
+
}
|
|
14918
|
+
let isFrameBoundary = false;
|
|
14919
|
+
if (isSlice) {
|
|
14920
|
+
let startsNewPicture;
|
|
14921
|
+
if (codec === "avc") {
|
|
14922
|
+
const headerBytes = chunk.subarray(payloadStart, payloadStart + AVC_SLICE_HEADER_PEEK_SIZE);
|
|
14923
|
+
const firstMacroblockInSlice = readExpGolomb(new Bitstream(headerBytes));
|
|
14924
|
+
startsNewPicture = !frameStartFound || firstMacroblockInSlice <= lastFirstMacroblockInSlice;
|
|
14925
|
+
lastFirstMacroblockInSlice = firstMacroblockInSlice;
|
|
14926
|
+
} else {
|
|
14927
|
+
startsNewPicture = chunk[payloadStart] >> 7 === 1;
|
|
14875
14928
|
}
|
|
14929
|
+
if (startsNewPicture) {
|
|
14930
|
+
if (frameStartFound) {
|
|
14931
|
+
isFrameBoundary = true;
|
|
14932
|
+
} else {
|
|
14933
|
+
frameStartFound = true;
|
|
14934
|
+
}
|
|
14935
|
+
}
|
|
14936
|
+
} else if (isAccessUnitStart && frameStartFound) {
|
|
14937
|
+
isFrameBoundary = true;
|
|
14938
|
+
}
|
|
14939
|
+
if (isFrameBoundary) {
|
|
14940
|
+
const packetLength = startCodePos - packetStartPos;
|
|
14941
|
+
this.seekTo(packetStartPos);
|
|
14942
|
+
return this.supplyPacket(packetLength, 0);
|
|
14876
14943
|
}
|
|
14877
14944
|
i += startCodeLength;
|
|
14878
14945
|
}
|
|
@@ -14880,7 +14947,7 @@ var Mediabunny = (() => {
|
|
|
14880
14947
|
break;
|
|
14881
14948
|
}
|
|
14882
14949
|
}
|
|
14883
|
-
if (packetStartPos !== null) {
|
|
14950
|
+
if (packetStartPos !== null && this.endPos > packetStartPos) {
|
|
14884
14951
|
const packetLength = this.endPos - packetStartPos;
|
|
14885
14952
|
this.seekTo(packetStartPos);
|
|
14886
14953
|
return this.supplyPacket(packetLength, 0);
|
|
@@ -15239,6 +15306,15 @@ var Mediabunny = (() => {
|
|
|
15239
15306
|
}
|
|
15240
15307
|
return lastSegment.timestamp + lastSegment.duration;
|
|
15241
15308
|
}
|
|
15309
|
+
async getUnixTimeForTimestamp(timestamp) {
|
|
15310
|
+
let segment = await this.getSegmentAt(timestamp, {});
|
|
15311
|
+
segment ??= await this.getFirstSegment({});
|
|
15312
|
+
if (!segment || segment.unixEpochTimestamp === null) {
|
|
15313
|
+
return null;
|
|
15314
|
+
}
|
|
15315
|
+
const elapsed = timestamp - segment.timestamp;
|
|
15316
|
+
return segment.unixEpochTimestamp + elapsed;
|
|
15317
|
+
}
|
|
15242
15318
|
async getTrackBackings() {
|
|
15243
15319
|
return this.trackBackingsPromise ??= (async () => {
|
|
15244
15320
|
const backings = [];
|
|
@@ -15396,7 +15472,10 @@ var Mediabunny = (() => {
|
|
|
15396
15472
|
async isRelativeToUnixEpoch() {
|
|
15397
15473
|
await this.hydrate();
|
|
15398
15474
|
assert(this.segmentedInput.firstSegment);
|
|
15399
|
-
return this.segmentedInput.firstSegment.
|
|
15475
|
+
return this.segmentedInput.firstSegment.unixEpochTimestamp === this.segmentedInput.firstSegment.timestamp;
|
|
15476
|
+
}
|
|
15477
|
+
getUnixTimeForTimestamp(timestamp) {
|
|
15478
|
+
return this.segmentedInput.getUnixTimeForTimestamp(timestamp);
|
|
15400
15479
|
}
|
|
15401
15480
|
getBitrate() {
|
|
15402
15481
|
return this.delegate(() => this.firstInputTrack._backing.getBitrate());
|
|
@@ -15986,7 +16065,10 @@ var Mediabunny = (() => {
|
|
|
15986
16065
|
throw new TypeError("options.fetchFn, when provided, must be a function.");
|
|
15987
16066
|
}
|
|
15988
16067
|
const urlString = url2 instanceof Request ? url2.url : url2 instanceof URL ? url2.href : url2;
|
|
15989
|
-
super(
|
|
16068
|
+
super(
|
|
16069
|
+
urlString,
|
|
16070
|
+
(request) => new _UrlSource(request.path, this._options)
|
|
16071
|
+
);
|
|
15990
16072
|
/** @internal */
|
|
15991
16073
|
this._offset = 0;
|
|
15992
16074
|
/** @internal */
|
|
@@ -16091,6 +16173,9 @@ var Mediabunny = (() => {
|
|
|
16091
16173
|
if (!response.ok) {
|
|
16092
16174
|
throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
|
|
16093
16175
|
}
|
|
16176
|
+
if (response.redirected) {
|
|
16177
|
+
this.rootPath = response.url;
|
|
16178
|
+
}
|
|
16094
16179
|
outer:
|
|
16095
16180
|
if (this._orchestrator.fileSize === null) {
|
|
16096
16181
|
const contentRange = response.headers.get("Content-Range");
|
|
@@ -16751,6 +16836,12 @@ var Mediabunny = (() => {
|
|
|
16751
16836
|
offset: innerStart
|
|
16752
16837
|
});
|
|
16753
16838
|
} else {
|
|
16839
|
+
promise.catch((error) => {
|
|
16840
|
+
if (this.disposed) {
|
|
16841
|
+
return;
|
|
16842
|
+
}
|
|
16843
|
+
throw error;
|
|
16844
|
+
});
|
|
16754
16845
|
}
|
|
16755
16846
|
return result;
|
|
16756
16847
|
}
|
|
@@ -16835,11 +16926,11 @@ var Mediabunny = (() => {
|
|
|
16835
16926
|
if (worker.pendingSlices.length > 0) {
|
|
16836
16927
|
worker.pendingSlices.forEach((x) => x.reject(error));
|
|
16837
16928
|
worker.pendingSlices.length = 0;
|
|
16838
|
-
} else {
|
|
16929
|
+
} else if (!worker.aborted && !this.disposed) {
|
|
16839
16930
|
throw error;
|
|
16840
16931
|
}
|
|
16841
16932
|
}).finally(() => {
|
|
16842
|
-
if (worker.running) {
|
|
16933
|
+
if (worker.running || this.workers.length >= this.options.maxWorkerCount) {
|
|
16843
16934
|
return;
|
|
16844
16935
|
}
|
|
16845
16936
|
if (this.queuedReads.length > 0) {
|
|
@@ -17152,6 +17243,7 @@ var Mediabunny = (() => {
|
|
|
17152
17243
|
this.streamHasEnded = false;
|
|
17153
17244
|
this.lastSegmentUpdateTime = -Infinity;
|
|
17154
17245
|
this.refreshInterval = 5;
|
|
17246
|
+
this.rootPath = path;
|
|
17155
17247
|
this.demuxer = demuxer;
|
|
17156
17248
|
this.nextLines = lines;
|
|
17157
17249
|
}
|
|
@@ -17187,19 +17279,24 @@ var Mediabunny = (() => {
|
|
|
17187
17279
|
if (!lines) {
|
|
17188
17280
|
var _stack = [];
|
|
17189
17281
|
try {
|
|
17190
|
-
const ref = __using(_stack, await this.demuxer.input._getSourceUncached({ path: this.
|
|
17282
|
+
const ref = __using(_stack, await this.demuxer.input._getSourceUncached({ path: this.rootPath, isRoot: false }));
|
|
17191
17283
|
const reader = new Reader12(ref.source);
|
|
17192
17284
|
const slice = await reader.requestEntireFile();
|
|
17193
17285
|
assert(slice);
|
|
17194
17286
|
lines = readAllLines(slice, slice.length, { ignore: canIgnoreLine });
|
|
17287
|
+
if (ref.source instanceof PathedSource) {
|
|
17288
|
+
this.rootPath = ref.source.rootPath;
|
|
17289
|
+
}
|
|
17195
17290
|
} catch (_) {
|
|
17196
17291
|
var _error = _, _hasError = true;
|
|
17197
17292
|
} finally {
|
|
17198
17293
|
__callDispose(_stack, _error, _hasError);
|
|
17199
17294
|
}
|
|
17200
17295
|
}
|
|
17296
|
+
const offsetTimestampsByDateTime = this.input._formatOptions.hls?.offsetTimestampsByDateTime !== false;
|
|
17201
17297
|
let headerRead = false;
|
|
17202
17298
|
let accumulatedTime = 0;
|
|
17299
|
+
let accumulatedUnixTime = null;
|
|
17203
17300
|
let nextSegmentDuration = null;
|
|
17204
17301
|
let currentKey = null;
|
|
17205
17302
|
let nextSequenceNumber = 0;
|
|
@@ -17235,6 +17332,7 @@ var Mediabunny = (() => {
|
|
|
17235
17332
|
currentFirstSegment = prevLastSegment.firstSegment;
|
|
17236
17333
|
currentInitSegment = prevLastSegment.initSegment;
|
|
17237
17334
|
lastProgramDateTimeSeconds = prevLastSegment.lastProgramDateTimeSeconds;
|
|
17335
|
+
accumulatedUnixTime = prevLastSegment.unixEpochTimestamp !== null ? prevLastSegment.unixEpochTimestamp + prevLastSegment.duration : null;
|
|
17238
17336
|
prevLastSegment = null;
|
|
17239
17337
|
}
|
|
17240
17338
|
}
|
|
@@ -17261,7 +17359,7 @@ var Mediabunny = (() => {
|
|
|
17261
17359
|
view2.setUint32(12, nextSequenceNumber);
|
|
17262
17360
|
key = { ...key, iv };
|
|
17263
17361
|
}
|
|
17264
|
-
const fullPath = joinPaths(this.
|
|
17362
|
+
const fullPath = joinPaths(this.rootPath, line);
|
|
17265
17363
|
const location = {
|
|
17266
17364
|
path: fullPath,
|
|
17267
17365
|
offset: nextByteRange?.offset ?? 0,
|
|
@@ -17269,7 +17367,7 @@ var Mediabunny = (() => {
|
|
|
17269
17367
|
};
|
|
17270
17368
|
const segment = {
|
|
17271
17369
|
timestamp: accumulatedTime,
|
|
17272
|
-
|
|
17370
|
+
unixEpochTimestamp: accumulatedUnixTime,
|
|
17273
17371
|
firstSegment: currentFirstSegment,
|
|
17274
17372
|
sequenceNumber: nextSequenceNumber,
|
|
17275
17373
|
location,
|
|
@@ -17280,6 +17378,9 @@ var Mediabunny = (() => {
|
|
|
17280
17378
|
};
|
|
17281
17379
|
currentFirstSegment ??= segment;
|
|
17282
17380
|
accumulatedTime += nextSegmentDuration;
|
|
17381
|
+
if (accumulatedUnixTime !== null) {
|
|
17382
|
+
accumulatedUnixTime += nextSegmentDuration;
|
|
17383
|
+
}
|
|
17283
17384
|
this.segments.push(segment);
|
|
17284
17385
|
} else {
|
|
17285
17386
|
}
|
|
@@ -17325,7 +17426,7 @@ var Mediabunny = (() => {
|
|
|
17325
17426
|
throw new Error("Invalid #EXT-X-MAP tag; BYTERANGE attribute must have a specified offset.");
|
|
17326
17427
|
}
|
|
17327
17428
|
if (!prevLastSegment) {
|
|
17328
|
-
const fullPath = joinPaths(this.
|
|
17429
|
+
const fullPath = joinPaths(this.rootPath, uri);
|
|
17329
17430
|
const location = {
|
|
17330
17431
|
path: fullPath,
|
|
17331
17432
|
offset: parsedByteRange?.offset ?? 0,
|
|
@@ -17336,7 +17437,7 @@ var Mediabunny = (() => {
|
|
|
17336
17437
|
}
|
|
17337
17438
|
const segment = {
|
|
17338
17439
|
timestamp: accumulatedTime,
|
|
17339
|
-
|
|
17440
|
+
unixEpochTimestamp: accumulatedUnixTime,
|
|
17340
17441
|
firstSegment: null,
|
|
17341
17442
|
sequenceNumber: null,
|
|
17342
17443
|
location,
|
|
@@ -17386,7 +17487,7 @@ var Mediabunny = (() => {
|
|
|
17386
17487
|
}
|
|
17387
17488
|
currentKey = {
|
|
17388
17489
|
method: "AES-128",
|
|
17389
|
-
keyUri: joinPaths(this.
|
|
17490
|
+
keyUri: joinPaths(this.rootPath, uri),
|
|
17390
17491
|
iv,
|
|
17391
17492
|
keyFormat
|
|
17392
17493
|
};
|
|
@@ -17456,13 +17557,17 @@ var Mediabunny = (() => {
|
|
|
17456
17557
|
const lastSegmentEnd = lastSegment.timestamp + lastSegment.duration;
|
|
17457
17558
|
const offset = dateTimeSeconds - lastSegmentEnd;
|
|
17458
17559
|
for (const segment of this.segments) {
|
|
17459
|
-
segment.timestamp
|
|
17460
|
-
|
|
17560
|
+
segment.unixEpochTimestamp = segment.timestamp + offset;
|
|
17561
|
+
if (offsetTimestampsByDateTime) {
|
|
17562
|
+
segment.timestamp = segment.unixEpochTimestamp;
|
|
17563
|
+
}
|
|
17461
17564
|
}
|
|
17462
|
-
accumulatedTime += offset;
|
|
17463
17565
|
}
|
|
17464
17566
|
lastProgramDateTimeSeconds = dateTimeSeconds;
|
|
17465
|
-
|
|
17567
|
+
accumulatedUnixTime = dateTimeSeconds;
|
|
17568
|
+
if (offsetTimestampsByDateTime) {
|
|
17569
|
+
accumulatedTime = dateTimeSeconds;
|
|
17570
|
+
}
|
|
17466
17571
|
} else if (line === TAG_DISCONTINUITY) {
|
|
17467
17572
|
currentFirstSegment = null;
|
|
17468
17573
|
} else if (line.startsWith(TAG_TARGETDURATION)) {
|
|
@@ -17679,10 +17784,10 @@ var Mediabunny = (() => {
|
|
|
17679
17784
|
readMetadata() {
|
|
17680
17785
|
return this.metadataPromise ??= (async () => {
|
|
17681
17786
|
assert(this.input._rootSource instanceof PathedSource);
|
|
17682
|
-
const { rootPath } = this.input._rootSource;
|
|
17683
17787
|
const slice = await this.input._reader.requestEntireFile();
|
|
17684
17788
|
assert(slice);
|
|
17685
17789
|
const lines = readAllLines(slice, slice.length, { ignore: canIgnoreLine });
|
|
17790
|
+
const { rootPath } = this.input._rootSource;
|
|
17686
17791
|
const variantStreams = [];
|
|
17687
17792
|
const mediaTags = [];
|
|
17688
17793
|
for (let i = 1; i < lines.length; i++) {
|
|
@@ -18197,6 +18302,9 @@ var Mediabunny = (() => {
|
|
|
18197
18302
|
isRelativeToUnixEpoch() {
|
|
18198
18303
|
return this.delegate(() => this.internalTrack.backingTrack.isRelativeToUnixEpoch());
|
|
18199
18304
|
}
|
|
18305
|
+
getUnixTimeForTimestamp(timestamp) {
|
|
18306
|
+
return this.delegate(() => this.internalTrack.backingTrack.getUnixTimeForTimestamp(timestamp));
|
|
18307
|
+
}
|
|
18200
18308
|
getBitrate() {
|
|
18201
18309
|
return this.internalTrack.peakBitrate;
|
|
18202
18310
|
}
|
|
@@ -18785,6 +18893,14 @@ var Mediabunny = (() => {
|
|
|
18785
18893
|
throw new TypeError(`${prefix}.isobmff.resolveKeyId, when provided, must be a function.`);
|
|
18786
18894
|
}
|
|
18787
18895
|
}
|
|
18896
|
+
if (options.hls !== void 0) {
|
|
18897
|
+
if (!options.hls || typeof options.hls !== "object") {
|
|
18898
|
+
throw new TypeError(`${prefix}.hls, when provided, must be an object.`);
|
|
18899
|
+
}
|
|
18900
|
+
if (options.hls.offsetTimestampsByDateTime !== void 0 && typeof options.hls.offsetTimestampsByDateTime !== "boolean") {
|
|
18901
|
+
throw new TypeError(`${prefix}.hls.offsetTimestampsByDateTime, when provided, must be a boolean.`);
|
|
18902
|
+
}
|
|
18903
|
+
}
|
|
18788
18904
|
};
|
|
18789
18905
|
|
|
18790
18906
|
// src/decode.ts
|
|
@@ -22845,14 +22961,29 @@ var Mediabunny = (() => {
|
|
|
22845
22961
|
}
|
|
22846
22962
|
};
|
|
22847
22963
|
};
|
|
22964
|
+
var validateVideoSinkDecoderOptions = (decoderOptions) => {
|
|
22965
|
+
if (!decoderOptions || typeof decoderOptions !== "object") {
|
|
22966
|
+
throw new TypeError("decoderOptions must be an object.");
|
|
22967
|
+
}
|
|
22968
|
+
if (decoderOptions.hardwareAcceleration !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(decoderOptions.hardwareAcceleration)) {
|
|
22969
|
+
throw new TypeError(
|
|
22970
|
+
"decoderOptions.hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'."
|
|
22971
|
+
);
|
|
22972
|
+
}
|
|
22973
|
+
if (decoderOptions.optimizeForLatency !== void 0 && typeof decoderOptions.optimizeForLatency !== "boolean") {
|
|
22974
|
+
throw new TypeError("decoderOptions.optimizeForLatency, when provided, must be a boolean.");
|
|
22975
|
+
}
|
|
22976
|
+
};
|
|
22848
22977
|
var VideoSampleSink = class extends BaseMediaSampleSink {
|
|
22849
22978
|
/** Creates a new {@link VideoSampleSink} for the given {@link InputVideoTrack}. */
|
|
22850
|
-
constructor(videoTrack) {
|
|
22979
|
+
constructor(videoTrack, decoderOptions = {}) {
|
|
22851
22980
|
if (!(videoTrack instanceof InputVideoTrack)) {
|
|
22852
22981
|
throw new TypeError("videoTrack must be an InputVideoTrack.");
|
|
22853
22982
|
}
|
|
22983
|
+
validateVideoSinkDecoderOptions(decoderOptions);
|
|
22854
22984
|
super();
|
|
22855
22985
|
this._track = videoTrack;
|
|
22986
|
+
this._decoderOptions = decoderOptions;
|
|
22856
22987
|
}
|
|
22857
22988
|
/** @internal */
|
|
22858
22989
|
async _createDecoder(onSample, onError) {
|
|
@@ -22863,9 +22994,14 @@ var Mediabunny = (() => {
|
|
|
22863
22994
|
}
|
|
22864
22995
|
const codec = await this._track.getCodec();
|
|
22865
22996
|
const rotation = await this._track.getRotation();
|
|
22866
|
-
|
|
22997
|
+
let decoderConfig = await this._track.getDecoderConfig();
|
|
22867
22998
|
const timeResolution = await this._track.getTimeResolution();
|
|
22868
22999
|
assert(codec && decoderConfig);
|
|
23000
|
+
decoderConfig = {
|
|
23001
|
+
...decoderConfig,
|
|
23002
|
+
hardwareAcceleration: this._decoderOptions.hardwareAcceleration,
|
|
23003
|
+
optimizeForLatency: this._decoderOptions.optimizeForLatency
|
|
23004
|
+
};
|
|
22869
23005
|
return new VideoDecoderWrapper(onSample, onError, codec, decoderConfig, rotation, timeResolution);
|
|
22870
23006
|
}
|
|
22871
23007
|
/** @internal */
|
|
@@ -22955,11 +23091,14 @@ var Mediabunny = (() => {
|
|
|
22955
23091
|
if (options.poolSize !== void 0 && (typeof options.poolSize !== "number" || !Number.isInteger(options.poolSize) || options.poolSize < 0)) {
|
|
22956
23092
|
throw new TypeError("poolSize must be a non-negative integer.");
|
|
22957
23093
|
}
|
|
23094
|
+
if (options.decoderOptions !== void 0) {
|
|
23095
|
+
validateVideoSinkDecoderOptions(options.decoderOptions);
|
|
23096
|
+
}
|
|
22958
23097
|
this._videoTrack = videoTrack;
|
|
22959
23098
|
this._alpha = options.alpha ?? false;
|
|
22960
23099
|
this._options = options;
|
|
22961
23100
|
this._fit = options.fit ?? "fill";
|
|
22962
|
-
this._videoSampleSink = new VideoSampleSink(videoTrack);
|
|
23101
|
+
this._videoSampleSink = new VideoSampleSink(videoTrack, options.decoderOptions);
|
|
22963
23102
|
this._canvasPool = Array.from({ length: options.poolSize ?? 0 }, () => null);
|
|
22964
23103
|
}
|
|
22965
23104
|
/** @internal */
|
|
@@ -23602,6 +23741,26 @@ var Mediabunny = (() => {
|
|
|
23602
23741
|
async isRelativeToUnixEpoch() {
|
|
23603
23742
|
return this._backing.isRelativeToUnixEpoch();
|
|
23604
23743
|
}
|
|
23744
|
+
/**
|
|
23745
|
+
* Returns the Unix time (in seconds since January 1, 1970 00:00:00 UTC) that the given track timestamp (in seconds)
|
|
23746
|
+
* maps to, or `null` if there is no such mapping. This provides a piecewise-continuous mapping from this track's
|
|
23747
|
+
* timestamp space into wall-clock time. Such mapping exists, for example, for HLS playlists with
|
|
23748
|
+
* `#EXT-X-PROGRAM-DATE-TIME` tags present.
|
|
23749
|
+
*
|
|
23750
|
+
* This mapping can be available even when {@link InputTrack.isRelativeToUnixEpoch} is `false`, for example for HLS
|
|
23751
|
+
* streams with program date time information but with {@link HlsInputFormatOptions.offsetTimestampsByDateTime}
|
|
23752
|
+
* set to `false`.
|
|
23753
|
+
*/
|
|
23754
|
+
async getUnixTimeForTimestamp(timestamp) {
|
|
23755
|
+
return this._backing.getUnixTimeForTimestamp(timestamp);
|
|
23756
|
+
}
|
|
23757
|
+
/**
|
|
23758
|
+
* Whether the track's timestamps can be mapped to Unix wall clock time via
|
|
23759
|
+
* {@link InputTrack.getUnixTimeForTimestamp}.
|
|
23760
|
+
*/
|
|
23761
|
+
async hasUnixTimeMapping() {
|
|
23762
|
+
return await this._backing.getUnixTimeForTimestamp(await this.getFirstTimestamp()) !== null;
|
|
23763
|
+
}
|
|
23605
23764
|
/** Returns the track's disposition, i.e. information about its intended usage. */
|
|
23606
23765
|
async getDisposition() {
|
|
23607
23766
|
return this._backing.getDisposition();
|