@torrent-tv/proxy 2.100.10 → 2.100.11
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
|
@@ -36,7 +36,15 @@ export class Renditions {
|
|
|
36
36
|
#host;
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
39
|
+
* The segment each viewer's move was last said to wait for on the output
|
|
40
|
+
* they are leaving, so that a wait is said once per segment.
|
|
41
|
+
*
|
|
42
|
+
* @type {Map<string, number>}
|
|
43
|
+
*/
|
|
44
|
+
#moveWaitsSaid = new Map();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {object} host - `viewerSecondsOn`, `audioStartSecondsFor`, `activeOutputFor`, `viewersOf`, `audioRenditionName`, `logger`, `placeViewer`, `viewerLeaves`, `createOrGetSession`, `planEncodersSoon`, `disposeSession`, `viewerPositionOf`, `encodeRuns`, `fileStartTimeReads`, `getCachedAudioTracks`, `getCachedMediaInfo`, `getContainerMediaInfo`, `localBaseUrl`, `outputTimes`, `outputs`, `quality`, `qualityOffer`, `segmentDurationSec`, `sourceFiles`, `viewers`, `generationOfRequest`, `givenOutputOf`, `noteGivenOutput`, `chosenOutputOf`, `chooseOutput`, `storedPieceReady`, `headersCompatible`, `audioChoiceOf`, `linkMbpsOf`, `qualityModeOf`, `noteServingVerdict`, `limitsFor`, `heightsChosenAs`, `highestGivenSegmentOf`, `sameHeightSwitchOf`, `noteSameHeightSwitch`, `switchingOnto`, `switchingFrom`, `segmentClosed`, `bufferedSecondsOf`, `minimumBufferSecondsFor`
|
|
40
48
|
*/
|
|
41
49
|
constructor(host) {
|
|
42
50
|
this.#host = host;
|
|
@@ -836,6 +844,14 @@ export class Renditions {
|
|
|
836
844
|
for (const consumerId of this.#host.switchingOnto(output)) {
|
|
837
845
|
this.#reconsiderSameHeightSwitch(base, consumerId, index);
|
|
838
846
|
}
|
|
847
|
+
// A segment closed on the output a viewer is LEAVING may be the one their
|
|
848
|
+
// move waits for (`#givenAndOpenOn`). It is behind the segment the move
|
|
849
|
+
// begins at by construction, so it is asked about with no index.
|
|
850
|
+
for (const consumerId of this.#host.switchingFrom?.(output) ?? []) {
|
|
851
|
+
if (this.#host.activeOutputFor({ base, consumerId, outputs: this.#host.outputs }) === output) {
|
|
852
|
+
this.#reconsiderSameHeightSwitch(base, consumerId, null);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
839
855
|
}
|
|
840
856
|
}
|
|
841
857
|
|
|
@@ -894,6 +910,28 @@ export class Renditions {
|
|
|
894
910
|
}
|
|
895
911
|
}
|
|
896
912
|
|
|
913
|
+
/**
|
|
914
|
+
* The segment just before the one a move would begin at, when it was given
|
|
915
|
+
* to this viewer from the output on their screen and is not closed there:
|
|
916
|
+
* the segment their held request waits for. Null otherwise.
|
|
917
|
+
*
|
|
918
|
+
* @param {HlsSession | null} current - The output on their screen.
|
|
919
|
+
* @param {string} consumerId
|
|
920
|
+
* @param {number[]} askedHeights
|
|
921
|
+
* @param {number} next - The segment the move would begin at.
|
|
922
|
+
* @returns {number | null}
|
|
923
|
+
*/
|
|
924
|
+
#givenAndOpenOn(current, consumerId, askedHeights, next) {
|
|
925
|
+
const segment = next - 1;
|
|
926
|
+
if (!current?.outputKey || segment < 0) {
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
const generation = this.#host.generationOfRequest(consumerId, Number.NaN);
|
|
930
|
+
const given = askedHeights.some((height) =>
|
|
931
|
+
this.#host.givenOutputOf(consumerId, generation, height, segment) === current.outputKey);
|
|
932
|
+
return given && !this.#host.segmentClosed(current.outputKey, segment) ? segment : null;
|
|
933
|
+
}
|
|
934
|
+
|
|
897
935
|
/**
|
|
898
936
|
* The segment this viewer will ask for next at these heights.
|
|
899
937
|
*
|
|
@@ -967,6 +1005,24 @@ export class Renditions {
|
|
|
967
1005
|
if (!this.#host.segmentClosed(prepared.outputKey ?? "", next)) {
|
|
968
1006
|
return;
|
|
969
1007
|
}
|
|
1008
|
+
// THE SEGMENT ALREADY GIVEN FROM THE OUTPUT ON SCREEN. A request is held by
|
|
1009
|
+
// the output it was given from, and leaving that output stops its encoder:
|
|
1010
|
+
// a segment given and not yet closed there would then be made by nobody.
|
|
1011
|
+
// On Home Assistant a viewer waiting for #2176 was moved from #2177 and
|
|
1012
|
+
// the picture stood for good (r71, torrent-tv/meta#178). The move waits for
|
|
1013
|
+
// that segment to be closed; an output whose encoding has failed for good
|
|
1014
|
+
// closes nothing, and its held request is the serving path's to answer.
|
|
1015
|
+
const open = this.#givenAndOpenOn(current, consumerId, move.askedHeights, next);
|
|
1016
|
+
if (open !== null && !this.#host.encodeRuns.hasFailed(current)) {
|
|
1017
|
+
if (this.#moveWaitsSaid.get(consumerId) !== open) {
|
|
1018
|
+
this.#moveWaitsSaid.set(consumerId, open);
|
|
1019
|
+
this.#host.logger.info(
|
|
1020
|
+
`transcode ${base.id} ${consumerId}'s move to ${move.outputKey} waits for #${open} on ` +
|
|
1021
|
+
`${current.outputKey}, given and not yet closed there`
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
970
1026
|
// THE CUSHION, for a move that is not urgent (roadmap item 98): a move up
|
|
971
1027
|
// is made once the viewer holds the cushion this file needs, and their
|
|
972
1028
|
// next report asks again until they do. A move DOWN is made at once — it
|
|
@@ -1026,6 +1082,7 @@ export class Renditions {
|
|
|
1026
1082
|
* @returns {void}
|
|
1027
1083
|
*/
|
|
1028
1084
|
#completeSameHeightSwitch(base, consumerId, move, prepared, current, next) {
|
|
1085
|
+
this.#moveWaitsSaid.delete(consumerId);
|
|
1029
1086
|
for (const height of move.askedHeights) {
|
|
1030
1087
|
this.#choose(consumerId, height, prepared, base);
|
|
1031
1088
|
}
|
|
@@ -1063,6 +1120,7 @@ export class Renditions {
|
|
|
1063
1120
|
* @returns {void}
|
|
1064
1121
|
*/
|
|
1065
1122
|
#cancelSameHeightSwitch(base, consumerId, reason) {
|
|
1123
|
+
this.#moveWaitsSaid.delete(consumerId);
|
|
1066
1124
|
const move = this.#host.sameHeightSwitchOf(consumerId);
|
|
1067
1125
|
if (!move) {
|
|
1068
1126
|
return;
|
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
stepBeingWarmedOf,
|
|
61
61
|
stepBeingWarmedSinceOf,
|
|
62
62
|
stepOnScreenOf,
|
|
63
|
+
switchingFrom,
|
|
63
64
|
switchingOnto,
|
|
64
65
|
watches
|
|
65
66
|
} from "../viewer/choices.js";
|
|
@@ -450,6 +451,7 @@ export function wireOutputs({
|
|
|
450
451
|
sameHeightSwitchOf: (consumerId) => sameHeightSwitchOf(parts.viewers, consumerId),
|
|
451
452
|
noteSameHeightSwitch: (consumerId, value) => noteSameHeightSwitch(parts.viewers, consumerId, value),
|
|
452
453
|
switchingOnto: (output) => switchingOnto(parts.viewers, output),
|
|
454
|
+
switchingFrom: (output) => switchingFrom(parts.viewers, output),
|
|
453
455
|
// What a viewer holds, and the cushion this file needs before a move that
|
|
454
456
|
// is not urgent is made (roadmap item 98).
|
|
455
457
|
bufferedSecondsOf: (consumerId) => bufferedSecondsOf(parts.viewers, consumerId),
|
|
@@ -565,6 +565,25 @@ export function switchingOnto(viewers, output) {
|
|
|
565
565
|
return found;
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
+
/**
|
|
569
|
+
* The present viewers on this output for whom a move onto ANOTHER output is
|
|
570
|
+
* being prepared: the ones a segment closed here may let go.
|
|
571
|
+
*
|
|
572
|
+
* @param {object} viewers
|
|
573
|
+
* @param {object} output
|
|
574
|
+
* @returns {string[]}
|
|
575
|
+
*/
|
|
576
|
+
export function switchingFrom(viewers, output) {
|
|
577
|
+
const found = [];
|
|
578
|
+
for (const [consumerId, viewer] of viewers.forOutput(output)) {
|
|
579
|
+
const move = viewer.sameHeightSwitch;
|
|
580
|
+
if (viewer.isPresent() && move && move.outputKey !== output.outputKey) {
|
|
581
|
+
found.push(consumerId);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
return found;
|
|
585
|
+
}
|
|
586
|
+
|
|
568
587
|
/**
|
|
569
588
|
* Every output a present viewer is being prepared onto, as ids.
|
|
570
589
|
*
|