@torrent-tv/proxy 2.21.1 → 2.22.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/CHANGELOG.md +5 -0
- package/package.json +1 -1
- package/services/hls-session-manager.js +55 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 2.22.0
|
|
2
|
+
|
|
3
|
+
- **Fix**: What a rung is OFFERED on is the startup measurement again, not the figure learned from a live session. The startup one is taken on a quiet machine against known clips and does not move; the learned one moves with whatever else the box was doing that second, and three field sessions in a row show the price of that: decoding learned at 0.87x, then at 1.34-1.57x, against calibration's 2.6x — each reading refusing another rung until the offer held a single height and the quality menu vanished with it.
|
|
4
|
+
- **New**: A live reading keeps the one thing it is authority on — itself. A rung that has actually been seen running below realtime, with the machine to itself, is withdrawn on that evidence whatever any prediction says. A rung nobody has run is judged by the startup measurement like any other, because a measurement of one rung is not a prediction about the rest.
|
|
5
|
+
|
|
1
6
|
## 2.21.1
|
|
2
7
|
|
|
3
8
|
- **Fix**: A cost is learned only from an encoder that had the machine to itself. Beside another encoder a reading already contains that other work, and the budget then ADDS the same work again when it predicts — so the price of a file grew with every reading. Measured in the field 2026-08-15: copying, whose truth is 7.9x, was learned as 2.03x; decoding, whose calibration clips say 2.6x, as 0.87x. Every re-encoded rung was then refused (`not offering 720p=0.56x … 240p=0.66x`), the offer collapsed to the one copied height, and the viewer lost the quality menu entirely.
|
package/package.json
CHANGED
|
@@ -4750,6 +4750,9 @@ export class HlsSessionManager {
|
|
|
4750
4750
|
heights: ordered,
|
|
4751
4751
|
ownHeight: own,
|
|
4752
4752
|
playingHeight: playing,
|
|
4753
|
+
// What each rung was actually seen doing in this session, which is the
|
|
4754
|
+
// only thing a live reading may speak for.
|
|
4755
|
+
measuredHeights: this.#measuredRungSpeeds(owner),
|
|
4753
4756
|
// What the family is already spending while a rung is considered. The
|
|
4754
4757
|
// picture being COPIED is the common case and used to be priced at
|
|
4755
4758
|
// nothing; measured, it is about an eighth of the machine.
|
|
@@ -4759,7 +4762,18 @@ export class HlsSessionManager {
|
|
|
4759
4762
|
fps: Number(owner.outputFps) || TRANSCODE_FPS,
|
|
4760
4763
|
source: owner.sourceDecode ?? null,
|
|
4761
4764
|
transcodeVideo: owner.transcodeVideo === true,
|
|
4762
|
-
|
|
4765
|
+
// NOT the learned cost. What a rung is OFFERED on is the startup
|
|
4766
|
+
// measurement, which is taken on a quiet machine against known clips and
|
|
4767
|
+
// does not move; the figure learned from a live session moves with
|
|
4768
|
+
// whatever else the box was doing at that second, and three field
|
|
4769
|
+
// sessions in a row (2026-08-15) show what that costs: 0.87x, then
|
|
4770
|
+
// 1.34-1.57x against calibration's 2.6x, each reading refusing another
|
|
4771
|
+
// rung until the offer held one height and the menu disappeared with it.
|
|
4772
|
+
//
|
|
4773
|
+
// The learned figure keeps its job — but only over the rung it was
|
|
4774
|
+
// measured ON, and only to take that one away (below). A measurement of
|
|
4775
|
+
// one rung is not a prediction about the others.
|
|
4776
|
+
observedDecodeCostSec: null
|
|
4763
4777
|
});
|
|
4764
4778
|
if (owner !== session) {
|
|
4765
4779
|
// An orphan: its base is gone, so this is the family's last word and
|
|
@@ -4896,6 +4910,10 @@ export class HlsSessionManager {
|
|
|
4896
4910
|
if (this.#runningEncoders() > 1) {
|
|
4897
4911
|
return;
|
|
4898
4912
|
}
|
|
4913
|
+
// What this rung did with the machine to itself — the one figure a live
|
|
4914
|
+
// reading is authority on, and what withdraws a rung that has been seen
|
|
4915
|
+
// failing without letting it speak for rungs nobody has run.
|
|
4916
|
+
session.lastAloneSpeed = speed;
|
|
4899
4917
|
if (speed < BUDGET_SPEED_OK && await this.#classifyTranscodeBound(session) === "download") {
|
|
4900
4918
|
return; // the torrent is what is short; this says nothing about the host
|
|
4901
4919
|
}
|
|
@@ -5158,6 +5176,32 @@ export class HlsSessionManager {
|
|
|
5158
5176
|
return cost;
|
|
5159
5177
|
}
|
|
5160
5178
|
|
|
5179
|
+
/**
|
|
5180
|
+
* The speed each rung of this family was last seen running at, when it was
|
|
5181
|
+
* running alone.
|
|
5182
|
+
*
|
|
5183
|
+
* A rung that has been watched failing is refused on that evidence; a rung
|
|
5184
|
+
* nobody has run says nothing about itself and is judged by the startup
|
|
5185
|
+
* measurement like any other.
|
|
5186
|
+
*
|
|
5187
|
+
* @param {HlsSession} base
|
|
5188
|
+
* @returns {Map<number, number>}
|
|
5189
|
+
*/
|
|
5190
|
+
#measuredRungSpeeds(base) {
|
|
5191
|
+
/** @type {Map<number, number>} */
|
|
5192
|
+
const speeds = new Map();
|
|
5193
|
+
for (const session of this.#familyOf(base)) {
|
|
5194
|
+
if (session.transcodeVideo !== true || !Number.isFinite(session.lastAloneSpeed)) {
|
|
5195
|
+
continue;
|
|
5196
|
+
}
|
|
5197
|
+
const height = this.variantHeightOf(session);
|
|
5198
|
+
if (height > 0) {
|
|
5199
|
+
speeds.set(height, session.lastAloneSpeed);
|
|
5200
|
+
}
|
|
5201
|
+
}
|
|
5202
|
+
return speeds;
|
|
5203
|
+
}
|
|
5204
|
+
|
|
5161
5205
|
#sustainableHeights({
|
|
5162
5206
|
heights,
|
|
5163
5207
|
ownHeight,
|
|
@@ -5168,7 +5212,8 @@ export class HlsSessionManager {
|
|
|
5168
5212
|
source,
|
|
5169
5213
|
transcodeVideo,
|
|
5170
5214
|
observedDecodeCostSec = null,
|
|
5171
|
-
concurrentCostSec = 0
|
|
5215
|
+
concurrentCostSec = 0,
|
|
5216
|
+
measuredHeights = null
|
|
5172
5217
|
}) {
|
|
5173
5218
|
const benchmark = this.softwarePresetBenchmark;
|
|
5174
5219
|
if (!Array.isArray(benchmark) || benchmark.length === 0 || sourceHeight <= 0 || sourceWidth <= 0) {
|
|
@@ -5200,6 +5245,14 @@ export class HlsSessionManager {
|
|
|
5200
5245
|
kept.push(height);
|
|
5201
5246
|
continue;
|
|
5202
5247
|
}
|
|
5248
|
+
// A rung this session has actually been seen running below realtime is
|
|
5249
|
+
// withdrawn on that evidence, whatever the prediction says. This is the
|
|
5250
|
+
// one thing a live reading is authority on: itself.
|
|
5251
|
+
const measured = measuredHeights?.get(height) ?? null;
|
|
5252
|
+
if (measured !== null && measured < 1) {
|
|
5253
|
+
dropped.push(`${height}p=${measured.toFixed(2)}x measured`);
|
|
5254
|
+
continue;
|
|
5255
|
+
}
|
|
5203
5256
|
const width = Math.round(((sourceWidth / sourceHeight) * height) / 2) * 2;
|
|
5204
5257
|
const { speed, sustainable } = canSustainOutput({
|
|
5205
5258
|
benchmark,
|