@torrent-tv/proxy 2.99.15 → 2.99.16
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
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { readVint } from "./ebml-reader.js";
|
|
22
|
-
import { isUnavailable } from "./unavailable.js";
|
|
23
22
|
|
|
24
23
|
/** An element id is at most four bytes and a size at most eight (RFC 8794 §4). */
|
|
25
24
|
export const MAX_HEADER_BYTES = 12;
|
|
@@ -65,10 +64,6 @@ export class ElementReader {
|
|
|
65
64
|
/** @type {number} */
|
|
66
65
|
#windowAt = 0;
|
|
67
66
|
|
|
68
|
-
/** Below this position a portion was found missing: read exactly there. */
|
|
69
|
-
#exactBefore = -1;
|
|
70
|
-
#narrow;
|
|
71
|
-
|
|
72
67
|
/**
|
|
73
68
|
* @param {object} params
|
|
74
69
|
* @param {(start: number, end: number) => Promise<Buffer>} params.read - Answers
|
|
@@ -84,13 +79,8 @@ export class ElementReader {
|
|
|
84
79
|
* last byte that can be read from `start` in one go. A read of what is
|
|
85
80
|
* downloaded must not run a prefetch past the end of the downloaded run,
|
|
86
81
|
* or a cluster that is whole would fail for the bytes after it.
|
|
87
|
-
* @param {boolean} [params.narrowWhenMissing] - When a prefetched portion is
|
|
88
|
-
* not all downloaded, read only the bytes asked for, and read exactly up to
|
|
89
|
-
* the end of that portion: what is not downloaded yet is then only what is
|
|
90
|
-
* needed, and the bytes before it are read.
|
|
91
82
|
*/
|
|
92
|
-
constructor({ read, fileSize, portionBytes = Number.POSITIVE_INFINITY, prefetch = false, readableUntil
|
|
93
|
-
this.#narrow = narrowWhenMissing;
|
|
83
|
+
constructor({ read, fileSize, portionBytes = Number.POSITIVE_INFINITY, prefetch = false, readableUntil }) {
|
|
94
84
|
this.#read = read;
|
|
95
85
|
this.#fileSize = fileSize;
|
|
96
86
|
this.#readableUntil = typeof readableUntil === "function" ? readableUntil : () => fileSize;
|
|
@@ -120,15 +110,8 @@ export class ElementReader {
|
|
|
120
110
|
return window.subarray(start - this.#windowAt, end - this.#windowAt);
|
|
121
111
|
}
|
|
122
112
|
const reach = Math.min(this.#fileSize, Math.max(end, this.#readableUntil(start)));
|
|
123
|
-
const span = this.#prefetch
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
got = await this.#read(start, start + span - 1);
|
|
127
|
-
} catch (error) {
|
|
128
|
-
if (!this.#narrow || span === end - start || !isUnavailable(error)) throw error;
|
|
129
|
-
this.#exactBefore = start + span;
|
|
130
|
-
got = await this.#read(start, end - 1);
|
|
131
|
-
}
|
|
113
|
+
const span = this.#prefetch ? Math.max(end - start, Math.min(this.#portion, reach - start)) : end - start;
|
|
114
|
+
const got = await this.#read(start, start + span - 1);
|
|
132
115
|
this.#window = got;
|
|
133
116
|
this.#windowAt = start;
|
|
134
117
|
return got.subarray(0, end - start);
|
|
@@ -48,10 +48,13 @@ export async function walkMatroskaPackets({ readRange, fileSize, portionBytes, l
|
|
|
48
48
|
// header at a time, each a read of a few bytes from the torrent thread, the
|
|
49
49
|
// soundtrack's second piece of a copied 1080p film took 29.6 s on Home
|
|
50
50
|
// Assistant while that thread was downloading (r52, torrent-tv/meta#178).
|
|
51
|
-
//
|
|
52
|
-
//
|
|
51
|
+
// A portion not all downloaded is asked for whole and the walk goes on from
|
|
52
|
+
// the same block once it is: read on header by header up to the gap, a walk
|
|
53
|
+
// held the file's reads 50 s and the picture's input waited behind it
|
|
54
|
+
// (r54). The headers lie throughout the portion, so it is all needed.
|
|
55
|
+
// Between clusters only their headers are read.
|
|
53
56
|
let readableUntil = null;
|
|
54
|
-
const reader = new ElementReader({ read: readRange, fileSize, portionBytes, prefetch: true,
|
|
57
|
+
const reader = new ElementReader({ read: readRange, fileSize, portionBytes, prefetch: true,
|
|
55
58
|
readableUntil: start => readableUntil ?? start });
|
|
56
59
|
const declared = recordedTracks(tracks, trackIds);
|
|
57
60
|
if (!state.packets) {
|
|
@@ -944,6 +944,25 @@ export class ViewerRequests {
|
|
|
944
944
|
}
|
|
945
945
|
// Totals that went back belong to a torrent added again: read on from them.
|
|
946
946
|
if (limit) source.limit = limit;
|
|
947
|
-
return source.free.snapshot()
|
|
947
|
+
return sourceService(source.free.snapshot(), source.delivered.snapshot());
|
|
948
948
|
}
|
|
949
949
|
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* The download service a source's forecast runs on: what the swarm carried
|
|
953
|
+
* while our selection held none of its connections back, but never less than
|
|
954
|
+
* what it carried in all. A stretch our selection held nothing back can be a
|
|
955
|
+
* moment with nothing to ask, and its rate then measures our asking: after a
|
|
956
|
+
* seek to 1000 s the forecast read 0 B/s from such a stretch while the torrent
|
|
957
|
+
* downloaded 5-18 MB/s, answered "service not advancing", and held the viewer
|
|
958
|
+
* (r54, torrent-tv/meta#178). What the swarm did carry, it can carry.
|
|
959
|
+
*
|
|
960
|
+
* @param {object | null} free - A rate summary (`RateTrend.snapshot`).
|
|
961
|
+
* @param {object | null} delivered
|
|
962
|
+
* @returns {object | null}
|
|
963
|
+
*/
|
|
964
|
+
export function sourceService(free, delivered) {
|
|
965
|
+
if (!free) return delivered;
|
|
966
|
+
if (!delivered) return free;
|
|
967
|
+
return delivered.lastValue > free.lastValue ? delivered : free;
|
|
968
|
+
}
|