@torrent-tv/proxy 2.92.1 → 2.92.2
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 +1 -1
- package/server.js +6 -3
- package/services/encode/EncodeRun.js +9 -0
- package/services/viewer/DownloadMaps.js +17 -3
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -409,13 +409,13 @@ export async function startProxyServer({
|
|
|
409
409
|
resolvePlayback: async (map) => {
|
|
410
410
|
if (map.zones.length === 0) return [];
|
|
411
411
|
const params = await containerOver(map);
|
|
412
|
-
if (!params) return [];
|
|
412
|
+
if (!params || !map.isCurrent()) return [];
|
|
413
413
|
const tracks = await containerOrchestrator.inspect(params, "tracks");
|
|
414
|
-
if (tracks.kind !== "result") return [];
|
|
414
|
+
if (tracks.kind !== "result" || !map.isCurrent()) return [];
|
|
415
415
|
const container = containerOrchestrator.known(map.sourceKey, map.fileIndex);
|
|
416
416
|
if (typeof container?.readPacketIndex !== "function") return [];
|
|
417
417
|
const media = await containerOrchestrator.inspect(params, "media-info");
|
|
418
|
-
if (media.kind !== "result") return [];
|
|
418
|
+
if (media.kind !== "result" || !map.isCurrent()) return [];
|
|
419
419
|
const shift = Number(media.value?.startTimeSeconds) || 0;
|
|
420
420
|
const converted = [];
|
|
421
421
|
const demands = [];
|
|
@@ -445,6 +445,7 @@ export async function startProxyServer({
|
|
|
445
445
|
}
|
|
446
446
|
demands.sort((left, right) => left.deadlineAt - right.deadlineAt || right.priority - left.priority || left.index - right.index);
|
|
447
447
|
for (const zone of demands) {
|
|
448
|
+
if (!map.isCurrent()) return [];
|
|
448
449
|
const selected = zone.tracks.map(choice => ({ choice, track: tracks.value.filter(track => track.type === choice.type)[choice.index] }));
|
|
449
450
|
if (selected.some(({ track }) => !track)) continue;
|
|
450
451
|
const wanted = selected.map(({ track }) => track);
|
|
@@ -454,8 +455,10 @@ export async function startProxyServer({
|
|
|
454
455
|
const intervalParams = await containerOver({ ...map, packetInterval: interval,
|
|
455
456
|
requestId: `download:${map.sourceKey}:${map.fileIndex}:${zone.outputKey}:${zone.index}`,
|
|
456
457
|
demand: { ...zone.owner, leadSeconds: zone.leadSeconds } });
|
|
458
|
+
if (!map.isCurrent()) return [];
|
|
457
459
|
if (!intervalParams) continue;
|
|
458
460
|
const packets = await containerOrchestrator.inspect(intervalParams, "packets");
|
|
461
|
+
if (!map.isCurrent()) return [];
|
|
459
462
|
if (packets.kind !== "result") continue;
|
|
460
463
|
const input = new SegmentInputs({ index: packets.value, tracks: wanted }).forInterval({ ...interval, mode: track => modes.get(track) });
|
|
461
464
|
if (input.kind !== "result") continue;
|
|
@@ -578,6 +578,15 @@ export class EncodeRun {
|
|
|
578
578
|
this.#publishClosed(this.#pendingClosed, name);
|
|
579
579
|
}
|
|
580
580
|
if (this.#publicationError) break;
|
|
581
|
+
const index = this.indexOfName(name);
|
|
582
|
+
const endOfWork = Number.isFinite(endOfRun(this)) ? this.to : this.lastSegmentIndex();
|
|
583
|
+
// A packet crossing the final cut can flush a following file. It may
|
|
584
|
+
// complete its predecessor, but no unadmitted interval can be published.
|
|
585
|
+
if (Number.isInteger(index) && Number.isInteger(endOfWork) && index > endOfWork) {
|
|
586
|
+
this.#closedTimings.delete(name);
|
|
587
|
+
this.#pendingClosed = null;
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
581
590
|
this.#pendingClosed = name;
|
|
582
591
|
}
|
|
583
592
|
}
|
|
@@ -44,7 +44,8 @@ export class DownloadMaps {
|
|
|
44
44
|
}
|
|
45
45
|
if (changed) await this.#emit(file);
|
|
46
46
|
if (revision !== file.revision) return;
|
|
47
|
-
const resolved = await this.#resolvePlayback({ sourceKey, fileIndex, durationSeconds, zones: file.sourceZones
|
|
47
|
+
const resolved = await this.#resolvePlayback({ sourceKey, fileIndex, durationSeconds, zones: file.sourceZones,
|
|
48
|
+
isCurrent: () => this.#files.get(`${sourceKey}:${fileIndex}`) === file && revision === file.revision });
|
|
48
49
|
if (revision !== file.revision) return;
|
|
49
50
|
file.zones = resolved;
|
|
50
51
|
return this.#emit(file);
|
|
@@ -53,7 +54,18 @@ export class DownloadMaps {
|
|
|
53
54
|
refresh(sourceKey, fileIndex) {
|
|
54
55
|
const file = this.#files.get(`${sourceKey}:${fileIndex}`);
|
|
55
56
|
if (!file) return Promise.resolve();
|
|
56
|
-
|
|
57
|
+
file.refreshAgain = true;
|
|
58
|
+
if (file.refreshPending) return file.refreshPending;
|
|
59
|
+
file.refreshPending = (async () => {
|
|
60
|
+
try {
|
|
61
|
+
do {
|
|
62
|
+
file.refreshAgain = false;
|
|
63
|
+
if (this.#files.get(`${sourceKey}:${fileIndex}`) !== file) return;
|
|
64
|
+
await this.playback({ sourceKey, fileIndex, durationSeconds: file.durationSeconds, zones: file.sourceZones });
|
|
65
|
+
} while (file.refreshAgain);
|
|
66
|
+
} finally { file.refreshPending = null; }
|
|
67
|
+
})();
|
|
68
|
+
return file.refreshPending;
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
epoch(sourceKey, fileIndex) {
|
|
@@ -95,7 +107,9 @@ export class DownloadMaps {
|
|
|
95
107
|
deadlineAt = Number.isFinite(current.deadlineAt) ? current.deadlineAt - leadSeconds * 1000 : current.deadlineAt;
|
|
96
108
|
}
|
|
97
109
|
file.metadata.set(statement, { ranges: result.ranges, requestId: result.requestId, priority, urgent, deadlineAt, interval, leadSeconds, scope, order });
|
|
98
|
-
} else {
|
|
110
|
+
} else if (result.kind !== "needs-memory") {
|
|
111
|
+
// Allocation refusal says nothing about whether previously missing
|
|
112
|
+
// source bytes have arrived. Keep their demand until the read resolves.
|
|
99
113
|
file.metadata.delete(statement);
|
|
100
114
|
}
|
|
101
115
|
return this.#emit(file);
|