@torrent-tv/proxy 2.105.7 → 2.105.9
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/package.json
CHANGED
package/server.js
CHANGED
|
@@ -22,7 +22,7 @@ import { probePackets } from "./services/media/probe-packets.js";
|
|
|
22
22
|
import { trackChoicesOf } from "./services/viewer/segment-demands.js";
|
|
23
23
|
import { PlaybackProjection } from "./services/torrent/PlaybackProjection.js";
|
|
24
24
|
import { SegmentInputTable } from "./services/viewer/segment-input-table.js";
|
|
25
|
-
import { SourcePreparation } from "./services/viewer/SourcePreparation.js";
|
|
25
|
+
import { SourcePreparation, preparationInterval } from "./services/viewer/SourcePreparation.js";
|
|
26
26
|
import { handleHealthzGet } from "./routes/healthz/get.js";
|
|
27
27
|
import { handleApiDeliverySinkGet } from "./routes/api/delivery-sink/get.js";
|
|
28
28
|
import { handleApiLinkProbeGet } from "./routes/api/link-probe/get.js";
|
|
@@ -1403,7 +1403,7 @@ export async function startProxyServer({
|
|
|
1403
1403
|
(work.ownerId === undefined || viewer.id === work.ownerId))
|
|
1404
1404
|
.map(viewer => viewer.positionSeconds() ?? 0);
|
|
1405
1405
|
const from = (positions.length ? Math.min(...positions) : 0) + (Number(info.value?.startTimeSeconds) || 0);
|
|
1406
|
-
params.packetInterval =
|
|
1406
|
+
params.packetInterval = preparationInterval(work.role, from, outputParts.segmentDurationSec);
|
|
1407
1407
|
if (work.role === "subtitle-embedded") {
|
|
1408
1408
|
const tracks = await containerOrchestrator.containerFor(params).then(container => container.readTracks());
|
|
1409
1409
|
const track = tracks.find(track => track.type === "subtitle" && track.declaredIndex === work.trackIndex);
|
|
@@ -291,8 +291,9 @@ export class EncodeRuns {
|
|
|
291
291
|
const endedAt = performance.now();
|
|
292
292
|
run.firstWaitTraceInputAt = endedAt;
|
|
293
293
|
const { sourceKey, process } = run.waitTraceInput ?? {};
|
|
294
|
+
const startedAt = run.waitTraceInput?.startedAt;
|
|
294
295
|
this.#host.observeWait?.(sourceKey, "process", { process, phase: "end", runToken, fileIndex, bytes,
|
|
295
|
-
startedAt
|
|
296
|
+
startedAt, endedAt, durationMs: Number.isFinite(startedAt) ? endedAt - startedAt : null });
|
|
296
297
|
const f2Process = process === "F1.a" ? "F2.a" : "F2.v";
|
|
297
298
|
run.waitTraceInput.f2Process = f2Process;
|
|
298
299
|
run.waitTraceInput.f2StartedAt = endedAt;
|
|
@@ -1290,9 +1291,10 @@ export class EncodeRuns {
|
|
|
1290
1291
|
}
|
|
1291
1292
|
});
|
|
1292
1293
|
const f1Process = session.spec.carries === "audio-only" ? "F1.a" : "F1.v";
|
|
1293
|
-
|
|
1294
|
+
const f1StartedAt = performance.now();
|
|
1295
|
+
run.waitTraceInput = { sourceKey: session.file.sourceKey, process: f1Process, startedAt: f1StartedAt };
|
|
1294
1296
|
this.#host.observeWait?.(session.file.sourceKey, "process", { process: f1Process,
|
|
1295
|
-
phase: "begin", runToken: inputToken, startedAt:
|
|
1297
|
+
phase: "begin", runToken: inputToken, startedAt: f1StartedAt, output: session.outputKey,
|
|
1296
1298
|
from: run.from, to: run.to });
|
|
1297
1299
|
if (admittedInput.original) {
|
|
1298
1300
|
run.originalInput = admittedInput;
|
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How many segments ahead of the viewer a chosen embedded subtitle is read.
|
|
3
|
+
*
|
|
4
|
+
* A reading window is taken again only when the viewer is planned again, which
|
|
5
|
+
* is when their report says they entered the next segment, and it starts where
|
|
6
|
+
* that report put them. Reports come every 1.5 s, so a window one segment long
|
|
7
|
+
* ended before the next one began whenever that report came later in its
|
|
8
|
+
* segment than the one before: a cue between the two was never read, and a
|
|
9
|
+
* cue just past a window was read only once the viewer had reached it (field
|
|
10
|
+
* 2026-10-22, Drifters 07: 1 of 27 cues missing, 7 late by 0.2-1.6 s,
|
|
11
|
+
* torrent-tv/meta#7). Two segments let each window reach past the start of the
|
|
12
|
+
* next while the viewer is planned at least once a segment.
|
|
13
|
+
*/
|
|
14
|
+
const SUBTITLE_SEGMENTS_AHEAD = 2;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The stretch of film one preparation read covers from where its viewers stand.
|
|
18
|
+
*
|
|
19
|
+
* @param {string | undefined} role
|
|
20
|
+
* @param {number} from - Seconds on the file's own clock.
|
|
21
|
+
* @param {number} segmentDurationSec
|
|
22
|
+
* @returns {{ from: number, to: number }}
|
|
23
|
+
*/
|
|
24
|
+
export function preparationInterval(role, from, segmentDurationSec) {
|
|
25
|
+
const segments = role === "subtitle-embedded" ? SUBTITLE_SEGMENTS_AHEAD : 1;
|
|
26
|
+
return { from, to: from + segments * segmentDurationSec };
|
|
27
|
+
}
|
|
28
|
+
|
|
1
29
|
/** Source preparation is derived from viewers before any output exists. */
|
|
2
30
|
export class SourcePreparation {
|
|
3
31
|
#viewers;
|