@torrent-tv/proxy 2.100.5 → 2.100.6
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
|
@@ -32,18 +32,28 @@ import { logger } from "../../utils/logger.js";
|
|
|
32
32
|
export const CONTAINER_HEAD_BYTES = 256 * 1024;
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* The size of the file and its OpenSubtitles hash, from the two edges.
|
|
36
|
-
*
|
|
35
|
+
* The size of the file and its OpenSubtitles hash, from the two edges. Nothing
|
|
36
|
+
* partial is kept: an edge that has not arrived is named instead.
|
|
37
|
+
*
|
|
38
|
+
* Both edges are read at once and both missing ones named in one answer. Read
|
|
39
|
+
* one after the other, a cold start asked the swarm for the file's last piece
|
|
40
|
+
* only once its first had arrived: on Home Assistant the last piece, which
|
|
41
|
+
* also holds a Matroska file's Cues, came 2.4 s after the first and the start
|
|
42
|
+
* waited for it (r66, torrent-tv/meta#178).
|
|
37
43
|
*
|
|
38
44
|
* @param {{ readRange: (start: number, end: number) => Promise<Buffer | null>, fileSize: number }} params
|
|
39
|
-
* @returns {Promise<{ hash: string, size: number } |
|
|
45
|
+
* @returns {Promise<{ hash: string, size: number } | { missing: Array<[number, number]> } | null>}
|
|
46
|
+
* `null` for a file too short to have one.
|
|
40
47
|
*/
|
|
41
48
|
async function readFingerprint({ readRange, fileSize }) {
|
|
42
49
|
if (!hasOshash(fileSize)) return null;
|
|
43
50
|
const read = strictReader(readRange, fileSize);
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
51
|
+
const reads = await Promise.allSettled([read(0, OSHASH_EDGE_BYTES - 1), read(fileSize - OSHASH_EDGE_BYTES, fileSize - 1)]);
|
|
52
|
+
const failed = reads.find(reading => reading.status === "rejected" && !isUnavailable(reading.reason));
|
|
53
|
+
if (failed) throw failed.reason;
|
|
54
|
+
const missing = reads.filter(reading => reading.status === "rejected").map(reading => [reading.reason.start, reading.reason.end]);
|
|
55
|
+
if (missing.length) return { missing };
|
|
56
|
+
return { hash: oshash(fileSize, reads[0].value, reads[1].value), size: fileSize };
|
|
47
57
|
}
|
|
48
58
|
|
|
49
59
|
/**
|
|
@@ -181,6 +191,10 @@ export class ContainerOrchestrator {
|
|
|
181
191
|
if (statement === "fingerprint") {
|
|
182
192
|
// A fact about the bytes at the two ends of the file, whatever the format.
|
|
183
193
|
const value = await readFingerprint(params);
|
|
194
|
+
if (value?.missing) {
|
|
195
|
+
logger.info(`media request=${requestId} needs bytes=${value.missing.map(([start, end]) => `${start}-${end}`).join(",")}`);
|
|
196
|
+
return { kind: "needs-ranges", ranges: value.missing, requestId };
|
|
197
|
+
}
|
|
184
198
|
return value ? { kind: "result", value, requestId } : { kind: "terminal", reason: "file-too-short", requestId };
|
|
185
199
|
}
|
|
186
200
|
const container = await this.containerFor(params);
|