@torrent-tv/proxy 2.9.89 → 2.9.91
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,12 @@
|
|
|
1
|
+
## 2.9.91
|
|
2
|
+
|
|
3
|
+
- **Fix**: The encoder no longer runs away from the viewer. Nothing bounded how far ahead it produced: measured 2026-08-04, three minutes after a film was opened the encode had reached 00:39:24 of a 01:26:51 source at 12.8x while the viewer was still at the start, and the torrent had pulled 80% of 4.7 GB to feed it — the pool owner's bandwidth and disk spent on a viewer who may watch two minutes, the pieces being read evicted from memory by pieces forty minutes ahead, and the swarm busy with anything but the segment being waited for. An encoder more than two minutes of content ahead of the last segment its viewer asked for is now **suspended**, and released once the viewer is within a minute of it — or at once when a segment is requested. Suspended rather than killed on purpose: restarting costs about nine seconds on this hardware, so a viewer reaching the end of the produced range would stall every time, while suspending keeps the process, its input and its position. POSIX only; where `SIGSTOP` does not exist the attempt fails once, is logged, and that session keeps the old behaviour. Every path that terminates an encoder now releases it first — a suspended process does not act on `SIGTERM` until it is continued, which would have hung the wait a seek performs before starting its replacement.
|
|
4
|
+
- **New**: A reader reports what it waited for. When a read blocks a second or more on a piece, the log names the piece, its position in the read, and the offset the read started at. The first segment after a seek-restart costs 9.2-9.4 s and there was no way to tell whether that is the swarm, the piece picker or ffmpeg; now there is.
|
|
5
|
+
|
|
6
|
+
## 2.9.90
|
|
7
|
+
|
|
8
|
+
- **New**: The output container is chosen per session, by the viewer, instead of once per proxy. `POST /api/transcode-sessions` accepts `segmentFormat`; `--segment-format` remains the default for a client that expresses no preference, and an unrecognised value falls back to it rather than to the library default. The browser is the only party that knows what its media stack will accept for the tracks it asked to be copied: a copied MP3 track cannot be appended from fMP4 at all (`audio/mp4; codecs="mp4a.69"` is refused by MediaSource) but works from MPEG-TS, which hls.js demuxes itself and hands to a plain `audio/mpeg` buffer — the same file, the same browser, silent loop one way and normal playback the other. Sessions are keyed by container too, so two viewers wanting different ones do not share an encoder. Nothing branches on the format outside `services/segment-formats/`; the manager now reads it off the session.
|
|
9
|
+
|
|
1
10
|
## 2.9.89
|
|
2
11
|
|
|
3
12
|
- **Fix**: What the torrent downloads is now decided by the readers, and by nobody else. Three places were claiming pieces for the same file and overwriting each other on every request: `acquireFile` selected the whole file, `prioritizeByteRange` selected from the read position to the end, and the reader selected its entire requested range. The reader's claim was the worst of the three — ffmpeg opens its input as `bytes <position>-<EOF>`, so the first read of a session claimed the **whole file** and marked **every piece critical**, and nothing ever gave it back, because that read is abandoned a second later when ffmpeg seeks. No later prioritisation could outrank a permanent whole-file claim, which is why 2.9.88 changed nothing measurable. Each read now holds a moving window ahead of its own head, as a **stream selection** — the kind WebTorrent counts rather than merges, so several parallel readers (the codec probe's head and tail, subtitles, one input per viewer) produce the union of their windows — and releases it on completion, cancellation and abandonment. `critical` marks only the piece being waited for and at most two more, which is the rule WebTorrent's own reader uses and what the flag is supposed to mean. `prioritizeByteRange` keeps only what readers cannot do: the read position for the resume figures, and the jump log line.
|
package/package.json
CHANGED
|
@@ -39,6 +39,11 @@ export async function handleApiTranscodeSessionsPost(req, reply, { hlsSessionMan
|
|
|
39
39
|
const manualQuality = payload.manualQuality === true;
|
|
40
40
|
const startPositionSeconds = Number(payload.startPositionSeconds);
|
|
41
41
|
const audioTrackIndex = Number(payload.audioTrackIndex);
|
|
42
|
+
// Which container to produce. The browser knows what its media stack will
|
|
43
|
+
// accept for the tracks it asked to be copied; an absent or unknown value
|
|
44
|
+
// leaves the proxy's own `--segment-format` in charge.
|
|
45
|
+
const segmentFormatId =
|
|
46
|
+
typeof payload.segmentFormat === "string" ? payload.segmentFormat.trim() : "";
|
|
42
47
|
|
|
43
48
|
if (!sourceKey || !Number.isInteger(fileIndex) || fileIndex < 0) {
|
|
44
49
|
return reply.code(400).send({ error: "sourceKey and valid fileIndex are required." });
|
|
@@ -60,7 +65,8 @@ export async function handleApiTranscodeSessionsPost(req, reply, { hlsSessionMan
|
|
|
60
65
|
? startPositionSeconds
|
|
61
66
|
: 0,
|
|
62
67
|
audioTrackIndex:
|
|
63
|
-
Number.isInteger(audioTrackIndex) && audioTrackIndex > 0 ? audioTrackIndex : 0
|
|
68
|
+
Number.isInteger(audioTrackIndex) && audioTrackIndex > 0 ? audioTrackIndex : 0,
|
|
69
|
+
segmentFormatId
|
|
64
70
|
});
|
|
65
71
|
return reply.send({
|
|
66
72
|
sessionId: session.id,
|