@torrent-tv/proxy 2.64.4 → 2.64.5
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 +4 -0
- package/package.json +1 -1
- package/services/hls-session-manager.js +28 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 2.64.5
|
|
2
|
+
|
|
3
|
+
- **Fix**: A rung measured at 0.007x is no longer kept just because it is on screen. The `playingHeight` exemption is now checked after the `measured < 1` withdrawal, so a 4K HEVC transcode at 0.007x on a CM4 (field 2026-08-31, 0.1x at 23:45 and 0.007x at 06:57, 0.04s buffered) is withdrawn and the offer can become empty instead of stalling the viewer with no way to downgrade. `ownHeight` is kept only for a copied source (`!transcodeVideo`), not for a re-encode already running at 0.18x.
|
|
4
|
+
|
|
1
5
|
## 2.64.4
|
|
2
6
|
|
|
3
7
|
- **Fix**: Piece store holds one `SharedArrayBuffer` per resident piece instead of a single growable pool that only ever grew. Evicting a piece deletes its buffer and the memory is reclaimable by GC — `committed` is now `resident * chunkLength`, not a high-water. On the field host a 6-piece 8 MiB overflow kept 48 MB committed; now it keeps 32 MB (roadmap 2).
|
package/package.json
CHANGED
|
@@ -7529,32 +7529,35 @@ export class HlsSessionManager {
|
|
|
7529
7529
|
/** @type {Map<number, number | null>} */
|
|
7530
7530
|
const predictedByHeight = new Map();
|
|
7531
7531
|
for (const height of heights) {
|
|
7532
|
-
// The rung ON SCREEN is never withdrawn, whatever anything says about it:
|
|
7533
|
-
// every route guard reads this list, so dropping it would 404 the next
|
|
7534
|
-
// segment of a stream that is playing.
|
|
7535
|
-
if (height === playingHeight) {
|
|
7536
|
-
kept.push(height);
|
|
7537
|
-
continue;
|
|
7538
|
-
}
|
|
7539
7532
|
// A rung this session has actually been seen running below realtime is
|
|
7540
7533
|
// withdrawn on that evidence, whatever the prediction says. This is the
|
|
7541
|
-
// one thing a live reading is authority on: itself
|
|
7542
|
-
//
|
|
7543
|
-
//
|
|
7544
|
-
//
|
|
7545
|
-
//
|
|
7546
|
-
//
|
|
7547
|
-
//
|
|
7548
|
-
//
|
|
7549
|
-
// measured failing at, then fail again, then step down, for ever. The
|
|
7550
|
-
// copied source height cannot reach this: `#measuredRungSpeeds` records
|
|
7551
|
-
// only sessions that re-encode, so a copy has no reading to be withdrawn
|
|
7552
|
-
// on, which is right — it costs no encoder.
|
|
7534
|
+
// one thing a live reading is authority on: itself. It is asked before
|
|
7535
|
+
// any exemption so a rung measured failing while on screen does not stay
|
|
7536
|
+
// offered because it was on screen when measured — otherwise a step
|
|
7537
|
+
// would ask for the one rung this machine has been measured failing at,
|
|
7538
|
+
// then fail again, then step down, for ever. A copied source height
|
|
7539
|
+
// cannot reach this: `#measuredRungSpeeds` records only sessions that
|
|
7540
|
+
// re-encode, so a copy has no reading to be withdrawn on, which is right
|
|
7541
|
+
// — it costs no encoder.
|
|
7553
7542
|
const measured = measuredHeights?.get(height) ?? null;
|
|
7554
7543
|
if (measured !== null && measured < 1) {
|
|
7544
|
+
// Even the rung on screen is withdrawn on measured failure: keeping it
|
|
7545
|
+
// would 404 the next segment, but keeping a rung measured at 0.007x
|
|
7546
|
+
// (field 2026-08-31, 4K HEVC on CM4) stalls the viewer for minutes with
|
|
7547
|
+
// 0.04s buffered and no way to downgrade because every other rung is
|
|
7548
|
+
// also dropped. Withdrawing it lets the offer become empty, which the
|
|
7549
|
+
// caller turns into an error the viewer can act on (try another proxy
|
|
7550
|
+
// or a lower source) instead of an endless spinner.
|
|
7555
7551
|
dropped.push(`${height}p=${measured.toFixed(2)}x measured`);
|
|
7556
7552
|
continue;
|
|
7557
7553
|
}
|
|
7554
|
+
// The rung ON SCREEN is kept only when it has not been measured failing
|
|
7555
|
+
// above. Keeping a rung measured at 0.007x would stall the viewer with
|
|
7556
|
+
// no path to a faster rung, which is what the field showed.
|
|
7557
|
+
if (height === playingHeight) {
|
|
7558
|
+
kept.push(height);
|
|
7559
|
+
continue;
|
|
7560
|
+
}
|
|
7558
7561
|
// The height an encoder is ALREADY producing, and the source's own height
|
|
7559
7562
|
// when the FAMILY serves it by copy — neither has to be predicted,
|
|
7560
7563
|
// because it is happening. A copied rung costs no encoder at all, so no
|
|
@@ -7567,9 +7570,13 @@ export class HlsSessionManager {
|
|
|
7567
7570
|
// A source height that would have to be RE-ENCODED is a prediction like
|
|
7568
7571
|
// any other: on a session whose budget stepped down to 480p, the source's
|
|
7569
7572
|
// 1080p is neither copied nor being produced, and keeping it unpriced
|
|
7570
|
-
// would offer exactly the kind of rung this refuses.
|
|
7573
|
+
// would offer exactly the kind of rung this refuses. Likewise, a rung
|
|
7574
|
+
// this session is already producing at 0.007x (field 2026-08-31, 4K HEVC
|
|
7575
|
+
// on CM4, 0.1x at 23:45 and 0.007x at 06:57) is not sustainable just
|
|
7576
|
+
// because it is running — keeping it offered no path to a faster rung
|
|
7577
|
+
// and left the viewer at 0.04s buffered with no downgrade.
|
|
7571
7578
|
if (
|
|
7572
|
-
height === ownHeight ||
|
|
7579
|
+
(height === ownHeight && !transcodeVideo) ||
|
|
7573
7580
|
(height === sourceHeight && !transcodeVideo)
|
|
7574
7581
|
) {
|
|
7575
7582
|
kept.push(height);
|