@torrent-tv/proxy 2.98.12 → 2.98.13

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torrent-tv/proxy",
3
- "version": "2.98.12",
3
+ "version": "2.98.13",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -13,6 +13,7 @@ import { contentionPenalty } from "./contention.js";
13
13
  import { LOOKAHEAD_PAUSE_SECONDS } from "./CushionReport.js";
14
14
  import { SpeedReadings } from "./SpeedReadings.js";
15
15
  import { nextInputAtFirstPiece } from "./next-input.js";
16
+ import { runOpenOf } from "./run-open.js";
16
17
  import { ENCODE_RUN_STATE, liveRunsOf, runStateOf, wireState } from "./encode-run-state.js";
17
18
  import { ENCODE_EXIT } from "./encode-exit.js";
18
19
  import { EncodeRun, endOfRun } from "./EncodeRun.js";
@@ -1330,11 +1331,14 @@ export class EncodeRuns {
1330
1331
  const grid = session.timeline?.published ?? session.timeline?.boundaries;
1331
1332
  const pieceSeconds = Number(grid?.[run.from + 1]) - Number(grid?.[run.from]);
1332
1333
  const speed = run.speedX > 0 ? run.speedX : this.#host.encodeOrchestrator.speedOn?.(session.outputKey) ?? 0;
1333
- if (!Number.isFinite(ended.firstNamedMs) || !(pieceSeconds > 0) || !(speed > 0)) return;
1334
1334
  // FFmpeg's reads may have waited for the stretch being copied; that wait
1335
- // is the copy's, and the stretch is sized from the open (torrent-tv/meta#178).
1336
- const waitedMs = Number.isFinite(ended.firstNamedWallMs) ? run.originalInput?.waitedBefore?.(ended.firstNamedWallMs) ?? 0 : 0;
1337
- const openSeconds = Math.max(0, (ended.firstNamedMs - waitedMs) / 1000 - pieceSeconds / speed);
1335
+ // is the copy's, and the stretch is sized from the open (`run-open.js`).
1336
+ const open = runOpenOf({
1337
+ firstNamedMs: ended.firstNamedMs, firstNamedWallMs: ended.firstNamedWallMs, startedAt: run.startedAt,
1338
+ waitedBefore: run.originalInput?.waitedBefore, pieceSeconds, speed
1339
+ });
1340
+ if (!open) return;
1341
+ const { openSeconds, waitedMs } = open;
1338
1342
  this.#host.encodeOrchestrator.noteOpen?.(session.outputKey ?? "", openSeconds);
1339
1343
  this.#host.logger.info(`encode input of run #${run.from}..#${run.to} on ${session.outputKey}: opened in ` +
1340
1344
  `${openSeconds.toFixed(2)}s (first piece named at ${ended.firstNamedMs}ms, ${pieceSeconds.toFixed(3)}s of film at ${speed.toFixed(2)}x` +
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file How long a run took to open its original input (torrent-tv/meta#178).
3
+ *
4
+ * Measured from the run's spawn to the name of its first closed piece, less
5
+ * what encoding that piece costs at the run's speed, and less the time
6
+ * FFmpeg's reads waited for the stretch being copied: that wait is the copy's,
7
+ * and the stretch is sized from the open. The input states those waits on the
8
+ * wall clock, so they are taken up to the wall-clock moment the first piece
9
+ * was named — the run's start plus its time to that name, not that time alone,
10
+ * which as a moment lay before every wait and counted none of them.
11
+ */
12
+
13
+ /**
14
+ * @param {object} params
15
+ * @param {number | null} params.firstNamedMs - Spawn to the first piece's name, pauses left out.
16
+ * @param {number | null} params.firstNamedWallMs - The same on the wall clock, pauses included.
17
+ * @param {number} params.startedAt - The run's spawn on the wall clock, ms.
18
+ * @param {((until: number) => number) | null | undefined} params.waitedBefore - The input's wall-clock waits for its copy before `until`, ms.
19
+ * @param {number} params.pieceSeconds - The first piece's film.
20
+ * @param {number} params.speed - Film seconds per second; 0 when not known.
21
+ * @returns {{ openSeconds: number, waitedMs: number } | null} Null where any term is unknown.
22
+ */
23
+ export function runOpenOf({ firstNamedMs, firstNamedWallMs, startedAt, waitedBefore, pieceSeconds, speed }) {
24
+ if (!Number.isFinite(firstNamedMs) || !(pieceSeconds > 0) || !(speed > 0)) return null;
25
+ const waitedMs = Number.isFinite(firstNamedWallMs) && startedAt > 0 && typeof waitedBefore === "function"
26
+ ? waitedBefore(startedAt + firstNamedWallMs)
27
+ : 0;
28
+ return { waitedMs, openSeconds: Math.max(0, (firstNamedMs - waitedMs) / 1000 - pieceSeconds / speed) };
29
+ }