@torrent-tv/proxy 2.9.137 → 2.9.138

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.138
2
+
3
+ - **Fix**: The init segment is now required to declare every track before it is cached — the requirement was computed and then ignored. One pass worked out how many tracks a complete header must have; the next returned the FIRST header it found, whatever it declared. A piece written before the video was muxed therefore supplied an audio-only header, and that header is kept for the session's whole life, because the player fetches `#EXT-X-MAP` exactly once and never again. The browser then has no video source buffer however much video arrives afterwards. Measured 2026-08-11 on the field host: `videoWidth=0`, `totalVideoFrames=0`, `readyState=4` — an element perfectly content, playing sound, with no picture in it for as long as the session lasted. A header short of a track is now kept only as a fallback and used only if no complete one is found, which is also when the log says so.
4
+
1
5
  ## 2.9.137
2
6
 
3
7
  - **New**: A session states the track set its output will carry, and sends it to the browser. The proxy knows the set exactly — it chose it: the command maps at most one video and at most one audio, each optional, and subtitles never enter the HLS output. That statement is now used twice, which is the point of making it: the init segment is checked against it here, and the browser checks what it actually received against the same statement (server 0.8.161). A track lost between the encoder and the element was previously noticed only by its absence, minutes later, as a black picture with working sound.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.9.137",
3
+ "version": "2.9.138",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "publishConfig": {
@@ -1619,9 +1619,26 @@ export class HlsSessionManager {
1619
1619
  continue;
1620
1620
  }
1621
1621
  const init = session.segmentFormat.extractInit(cached ?? await readFile(found));
1622
- if (init && init.length > 0) {
1622
+ if (!init || init.length === 0) {
1623
+ continue;
1624
+ }
1625
+ // The requirement computed above is APPLIED here. It was computed and
1626
+ // then ignored: this loop returned the first header it found, so a
1627
+ // piece written before the video was muxed supplied an audio-only
1628
+ // header — and that header is cached for the session's whole life,
1629
+ // because the player fetches `#EXT-X-MAP` once. Measured 2026-08-11:
1630
+ // `videoWidth=0`, `totalVideoFrames=0`, `readyState=4` — sound playing
1631
+ // and no picture, for as long as the session lasted.
1632
+ const tracks = typeof session.segmentFormat.countInitTracks === "function"
1633
+ ? session.segmentFormat.countInitTracks(init)
1634
+ : expectedTracks;
1635
+ if (tracks >= expectedTracks) {
1623
1636
  return init;
1624
1637
  }
1638
+ if (tracks > bestTracks) {
1639
+ best = init;
1640
+ bestTracks = tracks;
1641
+ }
1625
1642
  } catch {
1626
1643
  // Being written right now — try the next one.
1627
1644
  }
@@ -1635,6 +1652,7 @@ export class HlsSessionManager {
1635
1652
  `transcode ${session.id} no piece declared ${expectedTracks} tracks; ` +
1636
1653
  `serving an init with ${bestTracks}`
1637
1654
  );
1655
+ return best;
1638
1656
  }
1639
1657
  return best;
1640
1658
  }