@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 +8 -0
- package/CLAUDE.md +8 -5
- package/docs/container-architecture.md +25 -5
- package/package.json +1 -1
- package/services/audio-inventory.js +201 -411
- package/services/container/AviContainer.js +266 -81
- package/services/container/Container.js +248 -79
- package/services/container/ContainerFactory.js +67 -0
- package/services/container/MatroskaContainer.js +326 -7
- package/services/container/Mp4Container.js +372 -26
- package/services/hls-session-manager.js +2 -2
- package/services/playback-planner.js +43 -15
- package/services/torrent-worker/pool-adapter.js +352 -333
- package/services/tracks/AudioTrack.js +131 -40
- package/test/audio-inventory.test.js +176 -177
- package/test/matroska-cues-track.test.js +192 -192
- package/test/mp4-composition-times.test.js +0 -0
- package/test/video-facts.test.js +102 -0
- package/services/container-index/avi.js +0 -167
- package/services/container-index/index.js +0 -118
- package/services/container-index/matroska.js +0 -336
- package/services/container-index/mp4.js +0 -358
- /package/services/{container-index → container}/ebml-reader.js +0 -0
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
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
|