@torrent-tv/proxy 2.74.1 → 2.75.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 CHANGED
@@ -1,3 +1,11 @@
1
+ ## 2.75.0
2
+
3
+ - **New**: The picture's facts are read from BOTH readings that state them, which audio and subtitles have done since their flags were first read from the file and video never did. Every figure the encode is planned from — the size, the frame rate, whether it is HDR, how many bits a sample carries — came from ffmpeg's `-i` banner alone, while the `VideoTrack` the container declares was read and then used for nothing but a line in the log. Which reading answers is decided per field by what each one IS, and the rule is the one `readMediaInfo` already states: the coded size and the frame rate are the BANNER's, because what the encoder receives is what the decoder produced and the ladder and the scale filter must be sized to that; the bit depth and the HDR signalling are the CONTAINER's where it states them, because they are not properties of the decoded frames at all but the file saying how its samples are to be read, and ffmpeg prints them only as a side effect of naming a pixel format; the display size is the container's alone, the banner having no such field. Where the two disagree on something both state, the disagreement is now reported — it is a fact about the file and nothing could see it before. HDR is deliberately not compared: both sides give a boolean, and a boolean cannot say "I did not look", so a container with no Colour element and one stating SDR are the same `false`. That was found by the test, not by reading.
4
+ - **Chore**: One reconciliation of ffmpeg's banner with a container's own table, instead of two. The rule is the same for every media kind — align by position, check each pair on language or title, and drop the container reading WHOLE if one pair agrees on neither, because a wrong flag is worse than a missing one — and it was written twice, down to a `pairingHolds` that was byte-for-byte the same function under two names. `Container.alignWithBanner` is the alignment; `mergeSubtitleFlags` and `mergeAudioFlags` are the two flag lists, both on the container, because what they correct is what the container declares.
5
+ - **Chore**: Keyframe reading moved into the containers, and the third place that decided what a file is went with it. `container-index/matroska.js`, `mp4.js` and `avi.js` were each a specification speaking about its own container — the Cues table, `stss`/`stts`/`ctts` and the edit list, `idx1` and its keyframe flag — reachable only through that container's `readKeyframeIndex`. `container-index/index.js` sniffed the header a third time to pick between them; that is `ContainerFactory.readKeyframeIndex` now, over the factory's own sniff. `services/container-index/` is gone; the generic EBML element walker moved beside its only user.
6
+ - **Fix**: Folding the MP4 readers together put two `findMoov` implementations side by side, and they were not the same: one guarded against a box declaring size 0 — legal for the last box of a file, and an infinite loop for anything stepping over it — and the other did not. The guarded one is what survives, which is a defect removed rather than a tidy-up.
7
+ - **Chore**: The codec-name table is `AudioTrack`'s. Which name ffmpeg gives `A_AAC`, `ac-3` or a bare `.dts` is a property of the codec, and it decides whether the browser can play a soundtrack at all — the same shape as the markup table that moved to `TextSubtitleTrack` in 2.74.0.
8
+
1
9
  ## 2.74.1
2
10
 
3
11
  - **Chore**: The subtitle path chose a container twice, from two different kinds of evidence, and the two had to agree. Once by file extension, to decide which class to build; once by whether a track carried a sample list, to decide how to read its cues. Nothing enforced the agreement — a `.mkv` whose track somehow carried samples would have called a method Matroska does not have. There is one choice now and it is made from the BYTES: `ContainerFactory` sniffs the header, because that is what the muxer wrote while a name is what somebody typed, and only where the head is not downloaded — the cue walk asks the swarm for nothing — does the name answer instead. `Container.readHeldCues(plan, track, progress)` is then the one question: Matroska walks the clusters its Cues table names and fills every track from one walk, an MP4 reads the samples its own table states, and the caller chooses between them nowhere.
package/CLAUDE.md CHANGED
@@ -50,11 +50,14 @@ Linux-only host (e.g. POSIX-only signals must degrade elsewhere).
50
50
  - `controllers/` — interface layer: `PlaybackController` / `SubtitleController`
51
51
  (thin adapters over orchestrators; routes depend on controllers, not services).
52
52
  `routes/*` are now thin HTTP translators.
53
- - `container-index/` what is not specific to one media kind: EBML element
54
- walking and the Matroska/MP4/AVI keyframe tables. Used internally by
55
- `container/*`, deprecated as a direct import. Everything a container states
56
- about its own SUBTITLES — track table, Cues, blocks in a cluster, sample
57
- table, the walk of what is downloaded lives in the container class.
53
+ - Everything a container states about ITSELF lives in its own class: the
54
+ track table, the Cues, the keyframe times they name, the cluster positions,
55
+ the blocks inside a cluster, the MP4 sample table, and the walk of what is
56
+ downloaded. `services/container-index/` is gone; `container/ebml-reader.js`
57
+ is the format's byte-level grammar, not its statements, and is the only
58
+ piece kept apart. `ContainerFactory` is the ONE place that decides what a
59
+ file is — by sniffing the header, since that is what the muxer wrote — and
60
+ it also answers `readKeyframeIndex`.
58
61
  - `docs/download-architecture.md` — the two axes of downloading: what is
59
62
  wanted (`demand/`) against what the swarm is told (`download/`), why urgency
60
63
  is not a number given to the library, and why the speculative levels are
@@ -168,11 +168,31 @@ flowchart TB
168
168
 
169
169
  ## Legacy
170
170
 
171
- `services/container-index/` holds what is NOT specific to one media kind: EBML
172
- element walking, and the Matroska/MP4/AVI keyframe tables. Everything a container
173
- states about its own subtitles — the track table, the Cues, the blocks in a
174
- cluster, the sample table is in the container class itself. Direct imports from
175
- routes are deprecated use `orchestrators/` and `controllers/` instead.
171
+ Everything a container states about ITSELF is in its own class: the track table,
172
+ the Cues, the keyframe times they name, the cluster positions, the blocks inside
173
+ a cluster, the MP4 sample table. `services/container-index/` no longer exists.
174
+ What was kept apart is `container/ebml-reader.js` EBML element walking is the
175
+ format's grammar rather than any of its statements.
176
+
177
+ `ContainerFactory` is the one place that decides what a file IS. It sniffs the
178
+ header, because that is what the muxer wrote while a name is what somebody
179
+ typed, and it answers `readKeyframeIndex` for the same reason: doing it anywhere
180
+ else meant a third place making that decision. `ContainerFactory.byName` exists
181
+ for the one path that cannot sniff — the cue walk asks the swarm for nothing, so
182
+ a file whose head is not downloaded has only its name.
183
+
184
+ **Two readings of one file, and which answers.** ffmpeg's `-i` banner and the
185
+ container's own table both describe a file's tracks, and the rule is stated once
186
+ per media kind on `Container`. `alignWithBanner` lines them up by position and
187
+ CHECKS each pair on language or title; one pair agreeing on neither, or a length
188
+ that differs, drops the container reading whole, because a wrong flag is worse
189
+ than a missing one. `mergeSubtitleFlags`, `mergeAudioFlags` and
190
+ `mergeVideoFacts` then say which side answers for which field: flags the banner
191
+ cannot express come from the container; the coded size and frame rate come from
192
+ the probe, because the encoder receives what the decoder produced.
193
+
194
+ Direct imports from routes are deprecated — use `orchestrators/` and
195
+ `controllers/` instead.
176
196
 
177
197
  ## Flags matrix
178
198
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.74.1",
3
+ "version": "2.75.0",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "publishConfig": {