@torrent-tv/proxy 2.107.14 → 2.107.16
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/package.json
CHANGED
|
@@ -41,6 +41,34 @@ function sameInputs(left, right) {
|
|
|
41
41
|
return left.every((input, index) => input.sourceId === right[index].sourceId && input.ranges === right[index].ranges);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function forecastInputState(tracks, identity) {
|
|
45
|
+
if (!identity) return null;
|
|
46
|
+
const track = tracks.find(candidate => candidate.id === identity.trackId);
|
|
47
|
+
const segment = track?.segments.find(candidate => candidate.index === identity.segmentIndex);
|
|
48
|
+
const sourceInput = segment?.sourceInputs?.find(candidate => candidate.sourceId === identity.sourceId);
|
|
49
|
+
return {
|
|
50
|
+
sourceId: identity.sourceId,
|
|
51
|
+
trackId: identity.trackId,
|
|
52
|
+
segmentIndex: identity.segmentIndex,
|
|
53
|
+
phase: identity.phase,
|
|
54
|
+
rangesKnown: Array.isArray(sourceInput?.ranges),
|
|
55
|
+
rangeCount: Array.isArray(sourceInput?.ranges) ? sourceInput.ranges.length : null
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function forecastInputIdentity(state) {
|
|
60
|
+
return state && JSON.stringify([state.sourceId, state.trackId, state.segmentIndex, state.phase]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function observeForecastInput(observeWait, sourceKey, state, event) {
|
|
64
|
+
if (!state) return;
|
|
65
|
+
observeWait?.(sourceKey, "process", {
|
|
66
|
+
process: "P4.2", phase: event, at: performance.now(),
|
|
67
|
+
sourceId: state.sourceId, outputKey: state.trackId, segment: state.segmentIndex,
|
|
68
|
+
forecastPhase: state.phase, rangesKnown: state.rangesKnown, rangeCount: state.rangeCount
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
44
72
|
function segmentAddressOf(output, fileName) {
|
|
45
73
|
const format = output.segmentFormat;
|
|
46
74
|
if (!format) {
|
|
@@ -1090,6 +1118,16 @@ export class ViewerRequests {
|
|
|
1090
1118
|
if (waitEstimate) forecast.waitEstimate = waitEstimate;
|
|
1091
1119
|
}
|
|
1092
1120
|
const unavailableInput = forecast.unavailableSource;
|
|
1121
|
+
const previousInputState = measurement.forecastInputState ?? null;
|
|
1122
|
+
const currentInputState = forecastInputState(tracks, unavailableInput);
|
|
1123
|
+
if (previousInputState && forecastInputIdentity(previousInputState) !== forecastInputIdentity(currentInputState)) {
|
|
1124
|
+
observeForecastInput(this.#host.observeWait, session.file.sourceKey, previousInputState,
|
|
1125
|
+
currentInputState ? "forecast-blocker-replaced" : "forecast-blocker-cleared");
|
|
1126
|
+
}
|
|
1127
|
+
if (currentInputState && JSON.stringify(previousInputState) !== JSON.stringify(currentInputState)) {
|
|
1128
|
+
observeForecastInput(this.#host.observeWait, session.file.sourceKey, currentInputState, "forecast-blocked");
|
|
1129
|
+
}
|
|
1130
|
+
measurement.forecastInputState = currentInputState;
|
|
1093
1131
|
const forecastInputKey = unavailableInput ? JSON.stringify([
|
|
1094
1132
|
unavailableInput.sourceId, unavailableInput.trackId, unavailableInput.segmentIndex, unavailableInput.phase
|
|
1095
1133
|
]) : null;
|
|
@@ -85,7 +85,8 @@ export class SourcePreparation {
|
|
|
85
85
|
|
|
86
86
|
/** Current owners determine priority; old work never restores a withdrawn read. */
|
|
87
87
|
demandFor(work) {
|
|
88
|
-
if (work.role === "source-rest" && !this.#
|
|
88
|
+
if (work.role === "source-rest" && (!this.#playbackAppliedFor(work.sourceKey, work.fileIndex) ||
|
|
89
|
+
!this.#sourceRestNeededFor(work.sourceKey, work.fileIndex))) return null;
|
|
89
90
|
const handoffFileIndex = work.selected || (work.role === "source-rest" && work.ownerFileIndex === work.fileIndex)
|
|
90
91
|
? work.fileIndex : null;
|
|
91
92
|
const opening = Number.isInteger(handoffFileIndex) && this.#viewers.forSource(work.sourceKey).some(viewer =>
|