@torrent-tv/proxy 2.99.18 → 2.99.20
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
|
@@ -15,6 +15,7 @@ import { handleHealthGet } from "./routes/health/get.js";
|
|
|
15
15
|
import { handleMediaGet } from "./routes/media/get.js";
|
|
16
16
|
import { ProbeRequests } from "./services/media/ProbeRequests.js";
|
|
17
17
|
import { IndexMemory } from "./services/storage/IndexMemory.js";
|
|
18
|
+
import { LARGEST_GROWTH_BYTES } from "./services/media/container/PacketRecords.js";
|
|
18
19
|
import { probePackets } from "./services/media/probe-packets.js";
|
|
19
20
|
import { trackChoicesOf } from "./services/viewer/segment-demands.js";
|
|
20
21
|
import { PlaybackProjection } from "./services/torrent/PlaybackProjection.js";
|
|
@@ -770,6 +771,7 @@ export async function startProxyServer({
|
|
|
770
771
|
failed: (request, error) => logger.warn(`media request=${request.key} probe failed: ${error?.message ?? error}`)
|
|
771
772
|
});
|
|
772
773
|
const indexMemory = new IndexMemory({
|
|
774
|
+
growthBytes: LARGEST_GROWTH_BYTES,
|
|
773
775
|
reviseBudget: () => { void outputParts.machineBudget.revise("memory", "media metadata").catch(error => logger.warn(`packet index budget: ${error.message}`)); },
|
|
774
776
|
changed: () => { mediaReads.memoryChanged(); probeReads.memoryChanged(); outputParts.encodeInputs?.memoryChanged(); }
|
|
775
777
|
});
|
|
@@ -680,6 +680,26 @@ export class MatroskaContainer extends Container {
|
|
|
680
680
|
return cues.points.some(point => point.positions.some(position => !video || position.track === video.trackNumber));
|
|
681
681
|
}
|
|
682
682
|
|
|
683
|
+
/**
|
|
684
|
+
* Whether `statement` is answered from what this container has already
|
|
685
|
+
* read, so it may be answered beside a read of the same file in progress
|
|
686
|
+
* (`ContainerOrchestrator.inspect`), as an AVI's are. The picture's
|
|
687
|
+
* ranges are arithmetic over the Cues once they are read; asked behind a
|
|
688
|
+
* soundtrack's packet walk in the file's one queue, the picture's next
|
|
689
|
+
* input after a seek was ready only after the sound's, one piece every
|
|
690
|
+
* 7-8 s, where the two had been prepared side by side every 2 s (r57 against
|
|
691
|
+
* r50, torrent-tv/meta#178).
|
|
692
|
+
*
|
|
693
|
+
* @param {string} statement
|
|
694
|
+
* @returns {boolean}
|
|
695
|
+
*/
|
|
696
|
+
answersWithoutReading(statement) {
|
|
697
|
+
if (statement === "media-info") return this.mediaInfo?.durationSeconds != null;
|
|
698
|
+
if (statement === "source-navigation") return this.#cues !== undefined && this.#tracks !== null;
|
|
699
|
+
if (statement === "source-ranges") return this.#sourceSeekPoints !== null;
|
|
700
|
+
return false;
|
|
701
|
+
}
|
|
702
|
+
|
|
683
703
|
async readMappedSourceRanges(interval) { return this.readSourceRanges(interval); }
|
|
684
704
|
|
|
685
705
|
/**
|
|
@@ -9,6 +9,8 @@ const BLOCK_BYTES = 65536;
|
|
|
9
9
|
// Matroska soundtrack read in stretches: 144 tables of one 25-minute film held
|
|
10
10
|
// 18.9 MB for 3.7 MB of records (r47 reproduced, torrent-tv/meta#178).
|
|
11
11
|
const FIRST_BLOCK_BYTES = 4096;
|
|
12
|
+
/** The most one record can make a table take at once: a block of records and one of addresses. */
|
|
13
|
+
export const LARGEST_GROWTH_BYTES = 2 * BLOCK_BYTES;
|
|
12
14
|
const ADDRESS_BYTES = 8;
|
|
13
15
|
const HEADER_BYTES = 56;
|
|
14
16
|
|
|
@@ -7,18 +7,35 @@ export class IndexMemory {
|
|
|
7
7
|
#revise;
|
|
8
8
|
#changed;
|
|
9
9
|
#revisionQueued = false;
|
|
10
|
+
#growthBytes;
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} params
|
|
14
|
+
* @param {() => void} params.reviseBudget
|
|
15
|
+
* @param {() => void} params.changed
|
|
16
|
+
* @param {number} [params.growthBytes] - What one growth of a table can
|
|
17
|
+
* take at most, kept free beyond what is held while anything is held. A
|
|
18
|
+
* table grows a block at a time, each twice the last; allowed exactly what
|
|
19
|
+
* it held, each growth was refused first and its whole read tried again:
|
|
20
|
+
* a soundtrack piece after a seek was refused three times and ready after
|
|
21
|
+
* 53.7 s (r58, torrent-tv/meta#178).
|
|
22
|
+
*/
|
|
23
|
+
constructor({ reviseBudget, changed, growthBytes = 0 }) {
|
|
12
24
|
this.#revise = reviseBudget;
|
|
13
25
|
this.#changed = changed;
|
|
26
|
+
this.#growthBytes = growthBytes;
|
|
14
27
|
}
|
|
15
28
|
|
|
16
29
|
held() { return this.#held; }
|
|
17
30
|
packetBytes() { return this.#packetBytes; }
|
|
18
31
|
wanted() {
|
|
32
|
+
const short = [...this.#files.values()].reduce((sum, file) => sum + Math.max(0, file.needed - file.held), 0);
|
|
33
|
+
return this.#held + Math.max(short, this.#held > 0 ? this.#growthBytes : 0);
|
|
34
|
+
}
|
|
35
|
+
/** What is held and asked for, without the margin kept for growth. */
|
|
36
|
+
required() {
|
|
19
37
|
return this.#held + [...this.#files.values()].reduce((sum, file) => sum + Math.max(0, file.needed - file.held), 0);
|
|
20
38
|
}
|
|
21
|
-
required() { return this.wanted(); }
|
|
22
39
|
|
|
23
40
|
allow(bytes) {
|
|
24
41
|
const allowed = Math.max(0, bytes);
|