@torrent-tv/proxy 2.95.37 → 2.95.38

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.95.37",
3
+ "version": "2.95.38",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -2,6 +2,8 @@ import { createHash } from "node:crypto";
2
2
  import { matroskaInput, matroskaTrackIdentity } from "./MatroskaInput.js";
3
3
  import { pcmNormalization, normalizePcmSlices } from "./pcm-normalization.js";
4
4
 
5
+ const INPUT_WRITE_BATCH_BYTES = 64 * 1024;
6
+
5
7
  /** Acquire complete source ranges before any process can consume the input. */
6
8
  export async function admitInput({ sources, reserve, readRanges }) {
7
9
  if (!Array.isArray(sources) || sources.length === 0 || typeof reserve !== "function" || typeof readRanges !== "function") {
@@ -106,27 +108,37 @@ export async function writeAdmittedInput(input, stdin, { next = null } = {}) {
106
108
  let current = input, includeHeader = true;
107
109
  try {
108
110
  while (current) {
109
- if (JSON.stringify(current.tracks.map(input => matroskaTrackIdentity(input.track))) !== declarations) {
110
- throw new Error("Consecutive encoder input changed its declared tracks.");
111
- }
112
- for (let index = 0; index < current.tracks.length; index++) {
113
- const end = current.tracks[index].sourceEndSeconds;
114
- if (Number.isFinite(end)) input.tracks[index].sourceEndSeconds = end;
115
- }
116
- for await (const chunk of current.stream({ originSeconds, includeHeader, seen })) {
117
- await new Promise((resolve, reject) => {
118
- const failed = error => { stdin.off("error", failed); reject(error); };
119
- stdin.once("error", failed);
120
- stdin.write(chunk, error => {
121
- stdin.off("error", failed);
122
- if (error) reject(error);
123
- else resolve();
124
- });
125
- });
126
- }
127
- current.release();
128
- current = next ? await next() : null;
129
- includeHeader = false;
111
+ if (JSON.stringify(current.tracks.map(input => matroskaTrackIdentity(input.track))) !== declarations) {
112
+ throw new Error("Consecutive encoder input changed its declared tracks.");
113
+ }
114
+ for (let index = 0; index < current.tracks.length; index++) {
115
+ const end = current.tracks[index].sourceEndSeconds;
116
+ if (Number.isFinite(end)) input.tracks[index].sourceEndSeconds = end;
117
+ }
118
+ let batch = Buffer.allocUnsafe(INPUT_WRITE_BATCH_BYTES);
119
+ let used = 0;
120
+ const flush = async () => {
121
+ if (used === 0) return;
122
+ const chunk = batch.subarray(0, used);
123
+ batch = Buffer.allocUnsafe(INPUT_WRITE_BATCH_BYTES);
124
+ used = 0;
125
+ await writeChunk(stdin, chunk);
126
+ };
127
+ for await (const chunk of current.stream({ originSeconds, includeHeader, seen })) {
128
+ if (!Buffer.isBuffer(chunk)) throw new TypeError("Admitted input stream yielded a non-buffer chunk.");
129
+ let offset = 0;
130
+ while (offset < chunk.length) {
131
+ const copied = Math.min(INPUT_WRITE_BATCH_BYTES - used, chunk.length - offset);
132
+ chunk.copy(batch, used, offset, offset + copied);
133
+ used += copied;
134
+ offset += copied;
135
+ if (used === INPUT_WRITE_BATCH_BYTES) await flush();
136
+ }
137
+ }
138
+ await flush();
139
+ current.release();
140
+ current = next ? await next() : null;
141
+ includeHeader = false;
130
142
  }
131
143
  stdin.end();
132
144
  } finally {
@@ -134,3 +146,15 @@ export async function writeAdmittedInput(input, stdin, { next = null } = {}) {
134
146
  input.release();
135
147
  }
136
148
  }
149
+
150
+ function writeChunk(stdin, chunk) {
151
+ return new Promise((resolve, reject) => {
152
+ const failed = error => { stdin.off("error", failed); reject(error); };
153
+ stdin.once("error", failed);
154
+ stdin.write(chunk, error => {
155
+ stdin.off("error", failed);
156
+ if (error) reject(error);
157
+ else resolve();
158
+ });
159
+ });
160
+ }