@torrent-tv/proxy 2.67.0 → 2.69.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 +19 -0
- package/corpus.tmp.json +1 -0
- package/package.json +1 -1
- package/routes/api/subtitles/get.js +8 -3
- package/services/controllers/SubtitleController.js +24 -4
- package/services/data-channel-handler.js +5 -3
- package/services/language-detect.js +161 -6
- package/services/torrent-worker/background-fill.js +31 -9
- package/services/torrent-worker/piece-reader.js +30 -0
- package/services/torrent-worker/subtitle-cues.js +13 -1
- package/test/background-fill.test.js +34 -0
- package/test/subtitle-language.test.js +241 -0
- package/test/worker-channel.test.js +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 2.69.0
|
|
2
|
+
|
|
3
|
+
- **Fix**: The language detector no longer states an answer the text cannot support. Measured 2026-09-02 over Wikipedia extracts in seventeen languages, 120 random windows per language per length: franc's answer for Russian walks between Bulgarian, Serbian and Russian until about 650 characters, while Korean is settled by 40 and English by 130 — the figure is the language's own, because Russian competes with three neighbours for the same trigrams and Korean competes with nothing. The detector now asks franc for a candidate, refuses when the text is shorter than THAT candidate's measured figure, and refuses again when the answer does not survive losing either half of the text. The margin to the runner-up was tried first and rejected on measurement: it is 0.026 where the answer is wrong and 0.015 where it is right, so it separates nothing. `research/franc-boundary-2026-09-02.md`.
|
|
4
|
+
- **New**: The reading is re-taken as the film downloads. `warmSubtitleCues` re-runs detection over every cue held so far on each push and sends it as `detectedLanguage`; the browser moves the track's label onto it. This is what makes the refusal above cost the viewer nothing — a track opens as Unknown and becomes Russian a minute later, instead of opening as Bulgarian and staying wrong for the session. About 6 ms per push, measured; franc costs ~2 ms whatever the size.
|
|
5
|
+
- **Chore**: The stability test is worth its own line because it needs no table: across 38 400 trials franc alone was wrong 2197 times, and requiring the two halves to agree with the whole left 255 of those standing while keeping 81.8 % of the right answers.
|
|
6
|
+
- **Chore**: `test/worker-channel.test.js` waits for the chunk it is about instead of sleeping 50 ms and hoping. It has been on the flaky list since roadmap item 53, and this change is what pushed it over: the torrent worker gained one more module to load, and the chosen interval stopped being enough. A test that samples the clock does not test.
|
|
7
|
+
|
|
8
|
+
## 2.68.1
|
|
9
|
+
|
|
10
|
+
- **Fix**: A Russian subtitle file was reported to the viewer as English, and the proxy was the one saying so. Field 2026-09-01: `Sub/[Stan WarHammer & Nesitach]/[HorribleSubs] Drifters - 03 [1080p].ass` came back with `X-Subtitle-Language: en` and a body whose first cue is `Ты видишь их?`. The cause is what the detector was FED, not the detector. An ASS file is markup by half — measured on that file, 5040 Latin characters of Aegisub headers, style and font names, `Format:`/`Dialogue:` field prefixes and `{\…}` override groups against 5983 Cyrillic characters of dialogue — and `franc` scores letter trigrams over the whole string it is handed: `franc(the file) = eng`, `franc(the dialogue) = rus`. The markup-free WebVTT was already built two lines above and the detection was given the raw file anyway.
|
|
11
|
+
- **Fix**: The same mistake at the two other places a language is read, both found by looking rather than reported. An embedded ASS track was detected on its RAW cue text — a cluster-held cue is the dialogue row without its `Dialogue:` header, so it carries nine comma-separated fields and the override groups, which are Latin on a Russian track; it now reads the cues through `finalizeCues`, the same conversion that produces what is served. And the ffmpeg extraction path detected on the first 4096 BYTES of its WebVTT output, where a byte cut lands mid-character on any non-Latin track and most of those bytes are timestamps; it now reads the whole document's cue text.
|
|
12
|
+
- **Chore**: `language-detect.js` gains `cueTextOfVtt` — the words of a WebVTT document, with the header, `NOTE`/`STYLE`/`REGION` blocks, cue identifiers, timing lines, inline tags and character references removed — and `detectLanguageFromVtt` over it. One rule does most of it: a block with no timing line is not a cue. Six checks in `test/subtitle-language.test.js`.
|
|
13
|
+
- **Chore**: The embedded path now detects on every cue held so far rather than on the `fresh` subset being sent, because a re-subscription after a reconnect asks for only what that page missed and a handful of lines is not a sample of a language. This matters more than it sounds: measured 2026-09-01, `franc`'s answer among the Cyrillic languages is unstable on a small sample — one Russian text grown line by line answered `bul` at 129 characters, `srp` at 158 and 241, `bul` again at 292, then `rus` at every length from 337 to 881. Every change here gives the detector more text rather than less; the instability itself is not fixed and is recorded as its own roadmap item.
|
|
14
|
+
|
|
15
|
+
## 2.68.0
|
|
16
|
+
|
|
17
|
+
- **Fix**: The background fetch of a soundtrack now stands aside after a stall, not only during one. Pausing only while a reader is blocked is not enough on a swarm with no surplus: between stalls the fetch still takes bandwidth the picture needs, and the stalls themselves are the proof there was none to spare. Field 2026-08-31 — the swarm delivered 200-600 KB/s against the 399 KB/s the film eats, one piece waited 101 s after a seek, and the picture stood still 145.6 s before the player gave up. A chunk is fetched only when the stall count has not moved since the previous one, re-baselined after each quiet pause so it can resume; on a starving swarm it stops altogether, which is the right answer.
|
|
18
|
+
- **Chore**: `piece-reader.js` counts the stalls a torrent's readers have had, so work of lower importance can ask "did the viewer stall while I was busy?" — a stricter and more useful question than "is the viewer stalled right now".
|
|
19
|
+
|
|
1
20
|
## 2.67.0
|
|
2
21
|
|
|
3
22
|
- **New**: A soundtrack or subtitle file shipped beside the picture is fetched WHOLE as soon as the viewer opens the episode, using only the room their own reading leaves. The ordering is the design: what plays now comes first — the picture at the playhead, the soundtrack being heard, the subtitles being shown — the other tracks next, and reading the film far ahead last. The middle tier stays below the first by a condition that is measured rather than chosen: it fetches only while NO reader on the torrent is inside a wait, re-asked before every piece, because a torrent that was healthy a moment ago is not evidence about the next second. A soundtrack is about a twentieth of the picture, and having it on disk is what turns a later switch into a local read: in the field on 2026-08-31 the first piece of one took 27.7 s to arrive, which is longer than a switch is willing to wait.
|