@torrent-tv/proxy 2.101.25 → 2.101.26
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
|
@@ -75,10 +75,15 @@ export async function handleApiSourceFilesGet(req, reply, { sourceRegistry, torr
|
|
|
75
75
|
if (consumerId) viewers?.visibleFiles(consumerId, sourceKey, contents.items.map(item => item.fileIndex));
|
|
76
76
|
const generationRaw = typeof req.query?.generation === "string" ? req.query.generation : "";
|
|
77
77
|
const generation = generationRaw !== "" && /^\d+$/.test(generationRaw) ? Number(generationRaw) : null;
|
|
78
|
+
const linkMbps = Number(req.query?.linkMbps);
|
|
79
|
+
const linkSampleAgeMs = Number(req.query?.linkSampleAgeMs);
|
|
80
|
+
const earlyLink = Number.isFinite(linkMbps) && linkMbps > 0
|
|
81
|
+
? { linkMbps, linkSampleAgeMs: Number.isFinite(linkSampleAgeMs) && linkSampleAgeMs >= 0 ? linkSampleAgeMs : null }
|
|
82
|
+
: {};
|
|
78
83
|
const files = contents.files().map(file => {
|
|
79
84
|
if (!consumerId || !Number.isSafeInteger(generation) || file.kind !== "video" || file.excludedReason) return file;
|
|
80
85
|
const waitEstimate = viewerRequests?.waitEstimateForFile?.({ consumerId, generation, sourceKey,
|
|
81
|
-
fileIndex: file.fileIndex, fileName: file.relativePath ?? file.name, fileLength: file.length }) ?? null;
|
|
86
|
+
fileIndex: file.fileIndex, fileName: file.relativePath ?? file.name, fileLength: file.length, ...earlyLink }) ?? null;
|
|
82
87
|
return waitEstimate ? { ...file, waitEstimate } : file;
|
|
83
88
|
});
|
|
84
89
|
return reply.send({
|
|
@@ -37,9 +37,14 @@ export async function handleApiSourceStatsGet(req, reply, { sourceRegistry, torr
|
|
|
37
37
|
const requestedFileName = typeof req.query.fileName === "string" ? req.query.fileName : "";
|
|
38
38
|
const requestedFileLength = typeof req.query.fileLength === "string" && /^\d+$/.test(req.query.fileLength)
|
|
39
39
|
? Number(req.query.fileLength) : null;
|
|
40
|
+
const linkMbps = Number(req.query.linkMbps);
|
|
41
|
+
const linkSampleAgeMs = Number(req.query.linkSampleAgeMs);
|
|
42
|
+
const earlyLink = Number.isFinite(linkMbps) && linkMbps > 0
|
|
43
|
+
? { linkMbps, linkSampleAgeMs: Number.isFinite(linkSampleAgeMs) && linkSampleAgeMs >= 0 ? linkSampleAgeMs : null }
|
|
44
|
+
: {};
|
|
40
45
|
const initialEstimate = () => consumerId && Number.isSafeInteger(generation) && Number.isSafeInteger(fileIndex)
|
|
41
46
|
? viewerRequests?.waitEstimateForFile?.({ consumerId, generation, sourceKey, fileIndex,
|
|
42
|
-
fileName: requestedFileName, fileLength: requestedFileLength }) ?? null
|
|
47
|
+
fileName: requestedFileName, fileLength: requestedFileLength, ...earlyLink }) ?? null
|
|
43
48
|
: null;
|
|
44
49
|
|
|
45
50
|
let torrent;
|
|
@@ -137,7 +142,7 @@ export async function handleApiSourceStatsGet(req, reply, { sourceRegistry, torr
|
|
|
137
142
|
|
|
138
143
|
const waitEstimate = consumerId && Number.isSafeInteger(generation)
|
|
139
144
|
? viewerRequests?.waitEstimateForSource?.({ consumerId, generation, sourceKey, fileIndex,
|
|
140
|
-
fileName: torrent.files?.[fileIndex]?.name ?? requestedFileName, fileLength: requestedFileLength, stats }) ?? null
|
|
145
|
+
fileName: torrent.files?.[fileIndex]?.name ?? requestedFileName, fileLength: requestedFileLength, stats, ...earlyLink }) ?? null
|
|
141
146
|
: null;
|
|
142
147
|
return reply.send(waitEstimate ? { ...stats, waitEstimate } : stats);
|
|
143
148
|
}
|
|
@@ -280,6 +280,7 @@ export class LocalObservations {
|
|
|
280
280
|
fileLength: positive(features.fileLength),
|
|
281
281
|
downloadSpeed: nonNegative(features.downloadSpeed),
|
|
282
282
|
linkMbps: nonNegative(features.linkMbps),
|
|
283
|
+
linkSampleAgeMs: nonNegative(features.linkSampleAgeMs),
|
|
283
284
|
headerRemaining: nonNegative(features.headerRemaining),
|
|
284
285
|
peers: nonNegative(features.peers),
|
|
285
286
|
at: this.#now()
|
|
@@ -302,7 +303,7 @@ export class LocalObservations {
|
|
|
302
303
|
const readings = this.#entries.firstFrame[this.#firstFrameKey()] ?? [];
|
|
303
304
|
const candidates = readings.filter(reading => reading.extension === (features.extension ?? ""));
|
|
304
305
|
if (candidates.length === 0) return null;
|
|
305
|
-
const dimensions = ["fileLength", "downloadSpeed", "linkMbps", "headerRemaining", "peers"];
|
|
306
|
+
const dimensions = ["fileLength", "downloadSpeed", "linkMbps", "linkSampleAgeMs", "headerRemaining", "peers"];
|
|
306
307
|
const scales = new Map(dimensions.map(key => [key, median(candidates
|
|
307
308
|
.map(reading => nonNegative(reading[key]))
|
|
308
309
|
.filter(value => value !== null && value > 0))]));
|
|
@@ -106,7 +106,7 @@ export class ViewerRequests {
|
|
|
106
106
|
* @param {{ consumerId: string, generation: number, sourceKey: string, fileIndex: number, fileName: string, fileLength: number }} params
|
|
107
107
|
* @returns {object | null}
|
|
108
108
|
*/
|
|
109
|
-
waitEstimateForFile({ consumerId, generation, sourceKey, fileIndex, fileName, fileLength }) {
|
|
109
|
+
waitEstimateForFile({ consumerId, generation, sourceKey, fileIndex, fileName, fileLength, linkMbps, linkSampleAgeMs }) {
|
|
110
110
|
if (!consumerId || !Number.isSafeInteger(generation) || typeof sourceKey !== "string" ||
|
|
111
111
|
!Number.isSafeInteger(fileIndex) || fileIndex < 0) return null;
|
|
112
112
|
const waitId = `${sourceKey}:${fileIndex}:${generation}`;
|
|
@@ -116,7 +116,9 @@ export class ViewerRequests {
|
|
|
116
116
|
extension,
|
|
117
117
|
fileLength,
|
|
118
118
|
downloadSpeed: null,
|
|
119
|
-
linkMbps:
|
|
119
|
+
linkMbps: Number.isFinite(linkMbps) && linkMbps > 0
|
|
120
|
+
? linkMbps : this.#host.viewers.get(consumerId)?.linkReading()?.linkMbps,
|
|
121
|
+
linkSampleAgeMs: Number.isFinite(linkSampleAgeMs) && linkSampleAgeMs >= 0 ? linkSampleAgeMs : null,
|
|
120
122
|
headerRemaining: null,
|
|
121
123
|
peers: null
|
|
122
124
|
};
|
|
@@ -144,7 +146,8 @@ export class ViewerRequests {
|
|
|
144
146
|
* @param {{ consumerId: string, generation: number, sourceKey: string, fileIndex: number | null, fileName?: string, fileLength?: number | null, stats?: object }} params
|
|
145
147
|
* @returns {object | null}
|
|
146
148
|
*/
|
|
147
|
-
waitEstimateForSource({ consumerId, generation, sourceKey, fileIndex, fileName = "", fileLength = null,
|
|
149
|
+
waitEstimateForSource({ consumerId, generation, sourceKey, fileIndex, fileName = "", fileLength = null,
|
|
150
|
+
stats = {}, linkMbps, linkSampleAgeMs }) {
|
|
148
151
|
if (!consumerId || !Number.isSafeInteger(generation) || typeof sourceKey !== "string") return null;
|
|
149
152
|
const waitId = `${sourceKey}:${fileIndex ?? "all"}:${generation}`;
|
|
150
153
|
const key = `${consumerId}:${waitId}`;
|
|
@@ -154,7 +157,9 @@ export class ViewerRequests {
|
|
|
154
157
|
fileLength: Number.isFinite(stats?.fileLength) && stats.fileLength > 0
|
|
155
158
|
? stats.fileLength : fileLength,
|
|
156
159
|
downloadSpeed: stats?.downloadSpeed,
|
|
157
|
-
linkMbps:
|
|
160
|
+
linkMbps: Number.isFinite(linkMbps) && linkMbps > 0
|
|
161
|
+
? linkMbps : this.#host.viewers.get(consumerId)?.linkReading()?.linkMbps,
|
|
162
|
+
linkSampleAgeMs: Number.isFinite(linkSampleAgeMs) && linkSampleAgeMs >= 0 ? linkSampleAgeMs : null,
|
|
158
163
|
headerRemaining: Number.isFinite(stats?.headerBytes) && Number.isFinite(stats?.headerDownloadedBytes)
|
|
159
164
|
? Math.max(0, stats.headerBytes - stats.headerDownloadedBytes) : null,
|
|
160
165
|
peers: stats?.connectedPeers ?? stats?.numPeers
|