@torrent-tv/proxy 2.9.121 → 2.9.123
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/package.json +1 -1
- package/services/hls-session-manager.js +41 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 2.9.123
|
|
2
|
+
|
|
3
|
+
- **Fix**: The check added in 2.9.121 was deleting the file an encoder was writing into. A segment short of a track means one of two very different things — left behind by a run that was killed, or simply not finished yet — and treating them alike removed the file mid-write, after which ffmpeg went on writing to something nobody could open and the segment never appeared. Measured 2026-08-06: segment #225 was deleted 14 s into the run producing it and answered 404 thirty-three seconds later. The readiness rule could not prevent it, because it waves a segment through once the NEXT one exists and that next one had been left by an older run. Ownership decides it now: the current run writes from its start index upwards, so a file at or above that index while the run is alive is unfinished and is waited for, and only a file below it, or any file once no run is producing, is a leftover worth removing.
|
|
4
|
+
|
|
5
|
+
## 2.9.122
|
|
6
|
+
|
|
7
|
+
- **Fix**: A session created with a start position begins encoding there, instead of at the top of the file. The position was honoured everywhere except the one place that mattered: it went into the session key and into the log line, and then the first run started at index 0 regardless. Measured 2026-08-06 on a Retry after the proxy had restarted — the session was created with `start=1580s`, the encoder began at #0, the player asked for #152, and 45 s later the browser gave up with "no data arrived from the proxy" while the transcode ran happily at 9.9x through the opening credits.
|
|
8
|
+
|
|
1
9
|
## 2.9.121
|
|
2
10
|
|
|
3
11
|
- **Fix**: A segment that is short of a track is no longer served, which is what left a seek hanging with the proxy answering every request in 98 ms. A run that is terminated closes its current output file properly — trailing index and all — but the file holds only what had been muxed by then, and after a seek-restart that is routinely one track of two. Nothing about such a file looks unfinished: it exists, the next one exists, so the readiness rule called it done. Measured 2026-08-06 on a stuck session: segment #133 carried one `tfdt` where #131 and #134 carried two, and #132 was zero bytes. The fragments are already walked to stamp their timestamps, so counting the tracks in them costs nothing; a segment missing one is deleted and produced again.
|
package/package.json
CHANGED
|
@@ -1454,7 +1454,18 @@ export class HlsSessionManager {
|
|
|
1454
1454
|
`duration=${hasDuration ? formatSeconds(durationSeconds) : "unknown"} segments=${segmentCount}`
|
|
1455
1455
|
);
|
|
1456
1456
|
|
|
1457
|
-
|
|
1457
|
+
// Begin where the viewer asked, not at the top of the file. The position
|
|
1458
|
+
// was already honoured everywhere EXCEPT here: it went into the session key
|
|
1459
|
+
// and into the log line, and then the first run started at index 0 anyway.
|
|
1460
|
+
// Measured 2026-08-06 on a Retry after the proxy restarted — the session
|
|
1461
|
+
// was created with `start=1580s`, the encoder began at #0, the player
|
|
1462
|
+
// asked for #152, and 45 s later the browser gave up with "no data arrived
|
|
1463
|
+
// from the proxy" while the transcode ran happily at 9.9x through the
|
|
1464
|
+
// opening credits.
|
|
1465
|
+
const firstIndex = normalizedStartPosition > 0
|
|
1466
|
+
? this.#segmentIndexForTime(session, normalizedStartPosition)
|
|
1467
|
+
: 0;
|
|
1468
|
+
await this.#startEncodeRun(session, firstIndex);
|
|
1458
1469
|
|
|
1459
1470
|
try {
|
|
1460
1471
|
await this.waitUntilReady(session);
|
|
@@ -3407,14 +3418,38 @@ export class HlsSessionManager {
|
|
|
3407
3418
|
typeof session.segmentFormat.hasEveryTrack === "function" &&
|
|
3408
3419
|
!session.segmentFormat.hasEveryTrack(bytes, session.initBytes ?? null)
|
|
3409
3420
|
) {
|
|
3421
|
+
// Short of a track means one of two very different things, and the
|
|
3422
|
+
// first version of this check treated them alike — deleting the file
|
|
3423
|
+
// an encoder was writing INTO, so it went on writing to something
|
|
3424
|
+
// nobody could open and the segment never appeared. Measured
|
|
3425
|
+
// 2026-08-06: segment #225 was deleted 14 s into the run producing
|
|
3426
|
+
// it, and answered 404 thirty-three seconds later.
|
|
3427
|
+
//
|
|
3428
|
+
// The run that is producing this segment right now has simply not
|
|
3429
|
+
// finished it: wait, exactly as for a segment that does not exist
|
|
3430
|
+
// yet. Only a segment the CURRENT run has already moved past — the
|
|
3431
|
+
// next one exists, or no run is producing at all — is a leftover, and
|
|
3432
|
+
// only that one is worth removing so it can be made again.
|
|
3433
|
+
// Whose file is this? The current run writes from
|
|
3434
|
+
// `encodeStartIndex` upwards, so anything at or above that index
|
|
3435
|
+
// while the run is alive may simply be unfinished — the readiness
|
|
3436
|
+
// rule can wave it through on the strength of a NEXT segment left by
|
|
3437
|
+
// an older run, which is exactly how the file being written came to
|
|
3438
|
+
// be read. Anything below it, or any file at all once no run is
|
|
3439
|
+
// producing, belongs to a run that has ended.
|
|
3440
|
+
const stale = session.ffmpeg === null || index < (session.encodeStartIndex ?? 0);
|
|
3410
3441
|
logger.warn(
|
|
3411
3442
|
`transcode ${session.id} segment #${index} is short of a track — ` +
|
|
3412
|
-
|
|
3443
|
+
(stale
|
|
3444
|
+
? "left behind by a run that was terminated; producing it again"
|
|
3445
|
+
: "still being written; waiting for it")
|
|
3413
3446
|
);
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3447
|
+
if (stale) {
|
|
3448
|
+
try {
|
|
3449
|
+
await unlink(filePath);
|
|
3450
|
+
} catch {
|
|
3451
|
+
// Already gone, or being rewritten: either way nothing to do.
|
|
3452
|
+
}
|
|
3418
3453
|
}
|
|
3419
3454
|
return { kind: "warming-up" };
|
|
3420
3455
|
}
|