@torrent-tv/proxy 2.88.6 → 2.89.1

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.
Files changed (46) hide show
  1. package/AGENTS.md +21 -12
  2. package/CHANGELOG.md +2285 -2267
  3. package/assets/calibration/audio/NOTICE.md +19 -19
  4. package/assets/calibration/audio/manifest.json +98 -98
  5. package/docs/container-architecture.md +77 -22
  6. package/docs/playback-start-forecast.md +56 -56
  7. package/main2.cpuprofile +1 -0
  8. package/package.json +1 -1
  9. package/scripts/build-audio-samples.mjs +31 -31
  10. package/server.js +42 -27
  11. package/services/encode/OutputOpening.js +5 -4
  12. package/services/encode/audio-calibration.js +67 -67
  13. package/services/encode/audio-work-rate.js +15 -15
  14. package/services/media/ContainerOrchestrator.js +99 -46
  15. package/services/media/KeyframeTables.js +61 -21
  16. package/services/media/SubtitleCues.js +255 -183
  17. package/services/media/container/AviContainer.js +5 -3
  18. package/services/media/container/Container.js +66 -43
  19. package/services/media/container/ContainerFactory.js +8 -26
  20. package/services/media/container/MatroskaContainer.js +719 -1182
  21. package/services/media/container/Mp4Container.js +83 -73
  22. package/services/media/container/ebml-stream.js +174 -0
  23. package/services/media/container/matroska-clusters.js +1165 -0
  24. package/services/media/container/unavailable.js +77 -0
  25. package/services/media/tracks/ContainerTrack.js +9 -0
  26. package/services/media/tracks/TextSubtitleTrack.js +9 -1
  27. package/services/server/playback-readiness.js +516 -516
  28. package/services/torrent/worker/client.js +836 -765
  29. package/services/torrent/worker/held-bytes.js +84 -8
  30. package/services/torrent/worker/worker.js +10 -2
  31. package/services/transport/data-channel-handler.js +7 -3
  32. package/services/viewer/PriorityMap.js +31 -0
  33. package/test/audio-calibration.test.js +23 -23
  34. package/test/coalesce.test.js +39 -0
  35. package/test/held-read-ownership.test.js +77 -0
  36. package/test/helpers/held-file.js +50 -2
  37. package/test/helpers/matroska-file.js +296 -0
  38. package/test/keyframe-table-budget.test.js +21 -0
  39. package/test/matroska-cluster-discovery.test.js +323 -0
  40. package/test/reads-not-yet-arrived.test.js +218 -0
  41. package/test/subtitle-cue-walk.test.js +16 -1
  42. package/test/subtitle-plan-waits.test.js +125 -0
  43. package/test/subtitle-track-numbering.test.js +8 -3
  44. package/test/viewer-starts-on-map.test.js +27 -0
  45. package/test/whole-file-held-read.test.js +30 -0
  46. package/utils/coalesce.js +41 -0
package/AGENTS.md CHANGED
@@ -93,17 +93,25 @@ are recorded in `docs/browser-proxy-contract.md`.
93
93
  `ExternalSubtitleFile`. Spec-accurate flags (FlagForced only on subtitles per
94
94
  RFC 9559 §5.1.4.1, FlagOriginal/Commentary only on audio, tkhd
95
95
  track_enabled / alternate_group, elng BCP47).
96
- - `media/` application files: `ContainerOrchestrator` (detect + per-file
97
- cache of CONTAINERS, `getTracks`/`getMediaInfo`/`getKeyframeIndex` — it
98
- caches the container, never the answers, so nothing here is a second store
99
- of a fact somebody else owns), `KeyframeTables`,
96
+ - `media/` application files: `ContainerOrchestrator` (detect + the ONE
97
+ container per file, `containerFor`/`getTracks`/`getMediaInfo`/`getKeyframeIndex`;
98
+ the container keeps its own reading of each element it states — the Segment
99
+ layout, Tracks, Cues, MP4's `moov` — once it has been read), `KeyframeTables`,
100
100
  `SubtitleOrchestrator` (the track list and the cues behind
101
101
  `Container` tracks, warm/push — it is handed the walk, and `server.js` is
102
- what puts the two together), `SubtitleCues` (the walk itself: the plan, the
103
- found-order cursor, one walk of a file at a time). The walk
104
- itself is `MatroskaContainer.walkHeldClusters` / `Mp4Container.readHeldSamples`;
105
- what the torrent supplies is `held-bytes.js` — which ranges are downloaded
106
- whole, and a read of one that never fetches.
102
+ what puts the two together), `SubtitleCues` (the plan, the found-order
103
+ cursor, one walk of a file at a time, taking back withdrawn cues). It uses
104
+ the file's one container — it no longer builds its own. The walk itself is
105
+ `MatroskaContainer.readHeldCues` over `container/matroska-clusters.js` (which
106
+ also finds clusters the Cues table does not name) and
107
+ `Mp4Container.readHeldSamples`; what the torrent supplies is `held-bytes.js`
108
+ — which ranges are downloaded whole, and a read of one that never fetches
109
+ and answers at once with nothing where the range is not whole.
110
+ - **A read whose bytes have not arrived is not an answer about the file.**
111
+ Every container read is strict (`container/unavailable.js`): every byte, or
112
+ `BytesUnavailable`. A value, a proven absence, or a refusal of ours with its
113
+ reason may be kept; "not here yet" never is — not by a container, not by
114
+ `ContainerOrchestrator`, not by `KeyframeTables`, not by `SubtitleCues`.
107
115
  **`KeyframeTables` is where a file's keyframe table lives and the only thing
108
116
  that reads one.** The table is `container/KeyframeTable.js`, ONE object per
109
117
  file, handed out rather than copied — so a read that lands after a session
@@ -113,9 +121,10 @@ are recorded in `docs/browser-proxy-contract.md`.
113
121
  file that must be re-encoded for ever from a passing shortage of bytes off
114
122
  the swarm. One read per file whoever asks, the second asker joins the first,
115
123
  each caller's wait is bounded by the measured `KEYFRAME_TABLE_BUDGET_MS`
116
- while the READ is not, and a read that threw is never recorded as an answer.
117
- It is the ONLY store of the table: the container reads and does not
118
- remember, so there is one object per file and nothing to keep in step. The second reader is the packet probe in
124
+ while the READ is not, and a read that threw — `BytesUnavailable` included —
125
+ is never recorded as an answer; it is read again when pieces of the file
126
+ arrive (`readAgainIfUnanswered`). It is the ONLY store of the keyframe
127
+ answer; the container keeps the Cues reading the times are taken from. The second reader is the packet probe in
119
128
  `media/keyframe-probe.js`, which decodes rather than parsing; the fuller of the
120
129
  two answers is the one that stands (`media/keyframe-probe.js`).
121
130
  - `server/controllers/` — interface layer: `PlaybackController` / `SubtitleController`