@torrent-tv/proxy 2.9.66 → 2.9.67

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 CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.9.67
2
+
3
+ - **Fix**: A seek waited far longer than it needed to — 56 s measured in the field, of which roughly 50 s was self-inflicted. `SEEK_BACKOFF_SEGMENTS` (how far before the requested segment the encoder starts) was **12**, chosen when segments were an invented 4 s apart and the distance to a usable keyframe was unknown. Since 2.9.65 every boundary IS a real keyframe read from the container index, so the single preceding segment is guaranteed to start on one — and with real 10.43 s segments the old value meant encoding **125 s of content** before reaching the viewer position. Lowered to **1**. Observed: the encoder started at #332 for a seek to #344 and the requested segment only arrived 56 s later, while every segment after it was served in ~100 ms.
4
+
1
5
  ## 2.9.66
2
6
 
3
7
  - **New**: The container keyframe index now covers **MP4/MOV and AVI** as well as Matroska. MP4 reads the sync-sample and time-to-sample tables from `moov` — found by stepping over top-level box headers, so it works whether `moov` sits at the file start or the end, without scanning the gigabytes of `mdat` between them (verified on a 2 GB field file: **1145 keyframes in 625 ms**). AVI reads the trailing `idx1` table, still worth having because older releases are largely XviD-in-AVI and are exactly the files served by copying rather than re-encoding. Formats left out are documented in the module with the reason: MPEG-TS/M2TS carry no index anywhere by design, fragmented MP4 spreads timing across fragments instead of one table, and FLV/ASF have tables but effectively never appear in these releases.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.9.66",
3
+ "version": "2.9.67",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "publishConfig": {
@@ -72,26 +72,18 @@ const ENCODER_STALL_MS = 12_000;
72
72
  // producing nothing.
73
73
  // How many segments BEFORE the requested position the encoder starts.
74
74
  //
75
- // Required by how HLS players seek, per Apple's HLS authoring guidance: given a
76
- // position, the player locates the nearest IDR (keyframe) *preceding* it,
77
- // decodes from there, and only then presents from the requested point. So it
78
- // always fetches segments BELOW the target — measured 2026-08-02 on iOS: a seek
79
- // to #1082 fetched from #1074 (8 back), one to #1358 fetched from #1301 (57
80
- // back), and in the latter case the player asked for NOTHING at or above the
81
- // target, so an encoder starting exactly on it produced only files nobody was
82
- // waiting for and playback hung indefinitely.
75
+ // A player given a position decodes from the nearest keyframe PRECEDING it
76
+ // (Apple HLS authoring guidance), so it fetches segments below the target and
77
+ // an encoder starting exactly on it produces nothing anyone waits for.
83
78
  //
84
- // The observed backoff is not constant, so this is a floor, not the whole
85
- // answer: #fireSettledSeek also pulls the start down to the lowest segment the
86
- // player is actually waiting on when that is lower still. Costs a few seconds
87
- // of extra encoding per seek.
88
- const SEEK_BACKOFF_SEGMENTS = 12;
89
- // Hard limit on how far below the requested segment the start may be pulled by
90
- // `lowestAwaitedIndex`. Without it a stale request from earlier playback drags
91
- // the encoder across the whole file: field 2026-08-02, a seek to #1354 was
92
- // pulled to #123 — the start of the previous watch — because requests from
93
- // before the seek were still counted. Anything deeper than this is not the
94
- // preceding keyframe, it is a leftover.
79
+ // ONE segment is now enough. Since 2.9.65 every boundary IS a real keyframe
80
+ // (read from the container index), so the segment before the target is
81
+ // guaranteed to start on one. The old value of 12 dates from the invented 4 s
82
+ // grid, where the distance to a usable keyframe was unknown — and it became
83
+ // actively harmful once boundaries turned real: with 10.43 s segments it meant
84
+ // encoding 125 s of content before reaching the viewer's position. Field
85
+ // 2026-08-02: a seek took 56 s, of which ~50 s was this backoff.
86
+ const SEEK_BACKOFF_SEGMENTS = 1;
95
87
  const SEEK_PULL_LIMIT_SEGMENTS = 120;
96
88
  const SEEK_SETTLE_MS = 1_200;
97
89
  // Hard cap on the total settle wait, measured from the first far request of a