@torrent-tv/proxy 2.100.3 → 2.100.5

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.100.3",
3
+ "version": "2.100.5",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -654,11 +654,17 @@ export class HostLoad {
654
654
  // alone would print something like `ffmpeg=-598%`. Only pids present in
655
655
  // BOTH readings are counted, so a process that came or went contributes
656
656
  // nothing rather than a lie.
657
- const runs = encoding.flatMap((session) => this.#host.liveRunsOf(session)).filter((run) => Number.isInteger(run.process?.pid));
657
+ // Each run's pid and start are read BEFORE the readings are awaited: a run
658
+ // that ends meanwhile drops its process, and read after the await it threw
659
+ // `Cannot read properties of null (reading 'pid')`, seven times in one
660
+ // field session, each losing that reading (r64, torrent-tv/meta#178).
661
+ const runs = encoding.flatMap((session) => this.#host.liveRunsOf(session))
662
+ .filter((run) => Number.isInteger(run.process?.pid))
663
+ .map((run) => ({ pid: run.process.pid, startedAt: run.startedAt }));
658
664
  const [system, endedChildren, ...cpuReadings] = await Promise.all([
659
665
  this.#host.readSystemCpu(),
660
666
  this.#host.readEndedChildrenCpuSeconds?.() ?? null,
661
- ...runs.map((run) => this.#host.readProcessCpuSeconds(run.process.pid))
667
+ ...runs.map((run) => this.#host.readProcessCpuSeconds(run.pid))
662
668
  ]);
663
669
  /** @type {Map<number, number>} */
664
670
  const byPid = new Map();
@@ -667,8 +673,8 @@ export class HostLoad {
667
673
  runs.forEach((run, index) => {
668
674
  const seconds = cpuReadings[index];
669
675
  if (seconds !== null) {
670
- byPid.set(run.process.pid, seconds);
671
- startedAt.set(run.process.pid, run.startedAt);
676
+ byPid.set(run.pid, seconds);
677
+ startedAt.set(run.pid, run.startedAt);
672
678
  }
673
679
  });
674
680
  const sample = {
@@ -973,9 +973,15 @@ export class MatroskaContainer extends Container {
973
973
  Math.max(track.seekPrerollSeconds ?? 0, track.defaultDurationSeconds ?? 0)));
974
974
  let preceding = -1;
975
975
  for (let index = 0; index < points.length && points[index].seconds <= interval.from - preroll; index++) preceding = index;
976
- // The preceding cue's Cluster also retains audio that overlaps this cut
977
- // and decoder dependencies before the first presented packet.
978
- return preceding < 0 ? first : points[Math.max(0, preceding - 1)].at;
976
+ // A picture's leading frames may depend on the Cluster before its cue, so
977
+ // a picture begins one cue earlier. Sound and subtitles do not: the
978
+ // preroll above already reaches the cue whose Cluster holds a frame that
979
+ // overlaps the cut and the frames a decoder needs before it. Begun a cue
980
+ // earlier as well, a soundtrack's walk started a Cluster before the bytes
981
+ // the picture's input had copied for the same piece and could not be
982
+ // walked from them (r65, torrent-tv/meta#178).
983
+ const back = requested.some(track => track.type === "video") ? 1 : 0;
984
+ return preceding < 0 ? first : points[Math.max(0, preceding - back)].at;
979
985
  }
980
986
 
981
987
  /**