@torrent-tv/proxy 2.105.8 → 2.105.10

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.105.8",
3
+ "version": "2.105.10",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -109,11 +109,12 @@ export async function admitInput({ sources, reserve, readRanges }) {
109
109
  * the download a second time through it (Home Assistant 2026-10-12,
110
110
  * torrent-tv/meta#178).
111
111
  */
112
- export async function writeAdmittedInput(input, stdin, { next = null, waiting = null } = {}) {
112
+ export async function writeAdmittedInput(input, stdin, { next = null, waiting = null, onFirstInputBytes = null } = {}) {
113
113
  if (input?.kind !== "result") throw new TypeError("Only complete input may be written to an encoder.");
114
114
  const originSeconds = input.originSeconds;
115
115
  const declarations = JSON.stringify(input.tracks.map(input => matroskaTrackIdentity(input.track)));
116
116
  const seen = new Map();
117
+ let firstInputBytesNoted = false;
117
118
  let current = input, includeHeader = true;
118
119
  try {
119
120
  while (current) {
@@ -132,6 +133,10 @@ export async function writeAdmittedInput(input, stdin, { next = null, waiting =
132
133
  batch = Buffer.allocUnsafe(INPUT_WRITE_BATCH_BYTES);
133
134
  used = 0;
134
135
  await writeChunk(stdin, chunk);
136
+ if (!firstInputBytesNoted) {
137
+ firstInputBytesNoted = true;
138
+ onFirstInputBytes?.(chunk.length);
139
+ }
135
140
  };
136
141
  for await (const chunk of current.stream({ originSeconds, includeHeader, seen })) {
137
142
  if (!Buffer.isBuffer(chunk)) throw new TypeError("Admitted input stream yielded a non-buffer chunk.");
@@ -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: run.startedAt, endedAt, durationMs: endedAt - run.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
- run.waitTraceInput = { sourceKey: session.file.sourceKey, process: f1Process };
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: run.startedAt, output: session.outputKey,
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;
@@ -1339,11 +1341,14 @@ export class EncodeRuns {
1339
1341
  // begun at once (`next-packet-input.js`).
1340
1342
  const following = nextPacketInputs({ take: index => this.#host.encodeInputs.take(session, index, index),
1341
1343
  canAppend, first: nextIndex, last: ordered?.to ?? startIndex });
1342
- void writeAdmittedInput(admittedInput, run.process.stdin, { next: async () => {
1343
- const next = following.next(index => { run.to = index; });
1344
- if (next) run.admittedInputKeys.set(run.to, this.#inputFailures.key(next, inputParameters));
1345
- return next;
1346
- } }).catch(error => {
1344
+ void writeAdmittedInput(admittedInput, run.process.stdin, {
1345
+ onFirstInputBytes: bytes => this.noteFirstInputBytes(inputToken, session.file.fileIndex, bytes),
1346
+ next: async () => {
1347
+ const next = following.next(index => { run.to = index; });
1348
+ if (next) run.admittedInputKeys.set(run.to, this.#inputFailures.key(next, inputParameters));
1349
+ return next;
1350
+ }
1351
+ }).catch(error => {
1347
1352
  this.#host.logger.warn(`encode input output=${session.outputKey} segment=${safeIndex} write failed: ${error.message}`);
1348
1353
  run.process?.stdin?.destroy();
1349
1354
  }).finally(() => following.release());