@torrent-tv/proxy 2.62.0 → 2.64.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 +16 -0
- package/CLAUDE.md +17 -0
- package/bin/cli.js +520 -512
- package/docs/container-architecture.md +86 -0
- package/package.json +1 -1
- package/routes/api/playback-plan/post.js +5 -6
- package/routes/api/subtitles/get.js +39 -208
- package/services/container/AviContainer.js +45 -0
- package/services/container/Container.js +59 -0
- package/services/container/ContainerFactory.js +31 -0
- package/services/container/MatroskaContainer.js +289 -0
- package/services/container/Mp4Container.js +242 -0
- package/services/container/index.js +5 -0
- package/services/controllers/PlaybackController.js +33 -0
- package/services/controllers/SubtitleController.js +126 -0
- package/services/controllers/index.js +2 -0
- package/services/delivery-probe.js +532 -480
- package/services/memory-report.js +120 -15
- package/services/orchestrators/ContainerOrchestrator.js +89 -0
- package/services/orchestrators/SubtitleOrchestrator.js +101 -0
- package/services/orchestrators/index.js +2 -0
- package/services/piece-store/shared-piece-store.js +870 -791
- package/services/torrent-worker/worker.js +738 -706
- package/services/tracks/AudioTrack.js +40 -0
- package/services/tracks/ContainerTrack.js +72 -0
- package/services/tracks/ExternalSubtitleFile.js +27 -0
- package/services/tracks/ImageSubtitleTrack.js +19 -0
- package/services/tracks/SubtitleTrack.js +38 -0
- package/services/tracks/TextSubtitleTrack.js +29 -0
- package/services/tracks/VideoTrack.js +33 -0
- package/services/tracks/index.js +7 -0
- package/test/delivery-probe.test.js +213 -158
- package/test/memory-budget.test.js +89 -2
- package/test/worker-source-race.test.js +0 -76
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 2.64.0
|
|
2
|
+
|
|
3
|
+
- **Fix**: A reader sizes its window from the memory the store may hold NOW, not from the allowance it was created with. 2.63.0 made the allowance follow the machine but left the `capacity` getter answering the original reservation, and that getter is what `ceilingPieces` reads — so a reader would have gone on claiming pieces against an allowance the machine had already withdrawn.
|
|
4
|
+
- **New**: Container and track domain — `Container` (RFC 9559 / ISO 14496-12) with `MatroskaContainer` / `Mp4Container` / `AviContainer` via `ContainerFactory` (16-byte sniff), and `ContainerTrack` → `VideoTrack` / `AudioTrack` (`FlagOriginal`/`FlagCommentary`/`FlagVisualImpaired`) / `SubtitleTrack` → `TextSubtitleTrack` (`S_TEXT/UTF8`, `tx3g`, `wvtt`) / `ImageSubtitleTrack` (`PGS`, `VobSub`, `subp`) + `ExternalSubtitleFile`. Every class constructed from its spec section: `FlagForced` only on subtitles (RFC 9559 §5.1.4.1 0x55AA), `FlagEnabled`/`FlagDefault` + `LanguageBCP47` MUST on base, `track_enabled`/`alternate_group`/`elng` on MP4, `AVIIF_KEYFRAME` on AVI. `LanguageBCP47` overrides `Language` per MUST, disabled tracks kept for `declaredIndex` alignment with ffmpeg `0:s:N` (roadmap 62).
|
|
5
|
+
- **New**: Application layer — `ContainerOrchestrator` (per-file cache, `getTracks`/`getKeyframeIndex`) and `SubtitleOrchestrator` (wraps `torrent-worker/subtitle-cues.js` cluster walk behind track abstraction).
|
|
6
|
+
- **New**: Interface layer — `PlaybackController` / `SubtitleController`; `routes/api/playback-plan/post.js` and `routes/api/subtitles/get.js` delegate to controllers instead of calling services directly.
|
|
7
|
+
- **Chore**: `proxy/docs/container-architecture.md` with mermaid class/sequence diagrams and flags matrix; `proxy/CLAUDE.md` layout updated; `services/container-index/` marked as internal detail used by `container/*`.
|
|
8
|
+
|
|
9
|
+
## 2.63.0
|
|
10
|
+
|
|
11
|
+
- **New**: The piece store says what it has TAKEN, not only what it holds. `committed` and `on-disk` stand beside `resident` in its line. The two are different quantities and the difference is the growth that had no explanation: the pool only ever grows — `SharedArrayBuffer` has no shrink — so a piece spilled to disk returns its slot to the free list and its memory to nobody. On 2026-08-28 the store reported "144MB" while the process held 893 MB.
|
|
12
|
+
- **New**: The torrent worker reports its OWN isolate's memory. The piece pool is a `SharedArrayBuffer` allocated there, so the main thread's `arrayBuffers` cannot see it however carefully it is read — which is why the main line said `no torrent stores` in the same second the worker logged a live one. `rss` and the kernel's rollup stay on the main line, because they belong to the process and are read once.
|
|
13
|
+
- **New**: The process line carries `anon` from `/proc/self/smaps_rollup` and the free space where pieces spill. What neither isolate claims is now visible, and both limits are measured rather than declared — a budget for memory alone is half a budget when the overflow goes to a card the host boots from.
|
|
14
|
+
- **Fix**: A store's allowance follows the machine instead of being settled at birth. It was `MemAvailable` divided between the stores at the moment one was created, so a store opened on an idle machine kept an idle machine's allowance for life and went on growing while everything else competed for what was left. It is re-derived every minute, within the reservation the store was created with (`maxByteLength` was fixed from that and `grow()` cannot pass it). Lowering it frees nothing already committed — the pool cannot shrink — but it stops the growth, sends those pieces to disk, and says so in the log when a store is already past its new allowance.
|
|
15
|
+
- **Fix**: The delivery probe no longer calls a healthy connection stopped. Its allowance had one load-dependent term, our own send queue, and that queue is empty by construction — it drains the moment libdatachannel accepts the bytes, whether or not usrsctp then puts them on the wire. So a browser filling its cushion showed an empty queue, a small allowance and a large gap, which reads exactly like a stopped association: four `association-stopped` in the first two minutes of a healthy session on 2026-08-28, and deepening the cushion from 30 s to 120 s had made that burst four times longer. The browser reports its own transport-level received total with every echo, so the question is now answered by a counter rather than a threshold: while that total is advancing, bytes are crossing and no verdict of a stopped association stands. A browser that does not report it is judged exactly as before.
|
|
16
|
+
|
|
1
17
|
## 2.62.0
|
|
2
18
|
|
|
3
19
|
- **New**: Each session says what its cushion actually is, every half minute: how many seconds of film are ready ahead of the EARLIEST viewer's picture, roughly how many megabytes that is off the swarm, and how deep a buffer the browsers say they are holding. The three were never printed together and could not be reconstructed afterwards from anything that was — so whether deepening the browser's buffer (2.61.0) protected anybody, and what it cost the person hosting the proxy, had no answer. Every term is measured: the produced range from the segments on disk, the picture from the viewers' own reports, the byte rate from the file's length over its duration. The read window sits on top of the megabytes figure, so it is a floor.
|
package/CLAUDE.md
CHANGED
|
@@ -25,6 +25,23 @@ Linux-only host (e.g. POSIX-only signals must degrade elsewhere).
|
|
|
25
25
|
long-polls while a segment is being produced, returns retryable 503 (never
|
|
26
26
|
202 — hls.js can't consume it).
|
|
27
27
|
- `services/`:
|
|
28
|
+
- `container/` — domain layer: `Container` (abstract, RFC 9559 / ISO 14496-12),
|
|
29
|
+
`MatroskaContainer` / `Mp4Container` / `AviContainer`, `ContainerFactory`
|
|
30
|
+
(sniff 16 bytes → precise subclass). See `docs/container-architecture.md`.
|
|
31
|
+
- `tracks/` — domain layer: `ContainerTrack` (base: TrackNumber, declaredIndex,
|
|
32
|
+
language/BCP47, isEnabled/isDefault) → `VideoTrack` / `AudioTrack` /
|
|
33
|
+
`SubtitleTrack` → `TextSubtitleTrack` / `ImageSubtitleTrack`,
|
|
34
|
+
`ExternalSubtitleFile`. Spec-accurate flags (FlagForced only on subtitles per
|
|
35
|
+
RFC 9559 §5.1.4.1, FlagOriginal/Commentary only on audio, tkhd
|
|
36
|
+
track_enabled / alternate_group, elng BCP47).
|
|
37
|
+
- `orchestrators/` — application layer: `ContainerOrchestrator` (detect + per-file
|
|
38
|
+
cache, `getTracks`/`getKeyframeIndex`), `SubtitleOrchestrator` (wraps
|
|
39
|
+
`torrent-worker/subtitle-cues.js` cluster walk + `Container` tracks, warm/push).
|
|
40
|
+
- `controllers/` — interface layer: `PlaybackController` / `SubtitleController`
|
|
41
|
+
(thin adapters over orchestrators; routes depend on controllers, not services).
|
|
42
|
+
`routes/*` are now thin HTTP translators.
|
|
43
|
+
- `container-index/` — legacy readers (ebml-reader, matroska/mp4/avi keyframe and
|
|
44
|
+
subtitle tables) — used internally by `container/*`, deprecated as direct import.
|
|
28
45
|
- `playback-planner.js` — single ffmpeg probe returns audioCodec, videoCodec,
|
|
29
46
|
container, durationSeconds. `mode` is advisory; the browser decides.
|
|
30
47
|
- `hls-session-manager.js` — one ffmpeg per (source, file, settings). Serves a
|