@torrent-tv/proxy 2.107.12 → 2.107.14
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
|
@@ -1383,6 +1383,9 @@ export async function startProxyServer({
|
|
|
1383
1383
|
const held = await torrentPool.heldRangesOf(torrent, work.fileIndex);
|
|
1384
1384
|
return work.inputRanges.every(([start, end]) => held.some(([from, to]) => from <= start && to >= end));
|
|
1385
1385
|
},
|
|
1386
|
+
sourceRestNeededFor: (sourceKey, fileIndex) => ![...outputParts.outputs.values()].some(output =>
|
|
1387
|
+
output.file?.sourceKey === sourceKey && output.file?.fileIndex === fileIndex &&
|
|
1388
|
+
outputParts.viewers.forOutput(output).size > 0),
|
|
1386
1389
|
playbackAppliedFor: (sourceKey, fileIndex) => downloadMaps.hasAppliedPlayback(sourceKey, fileIndex),
|
|
1387
1390
|
readyChanged: (work, ready) => logger.info(`source urgent request=${work.requestId} viewer=${work.ownerId} ` +
|
|
1388
1391
|
`source=${work.sourceKey} file=${work.fileIndex} inputReady=${ready}`),
|
|
@@ -228,8 +228,14 @@ export class PacketIndex {
|
|
|
228
228
|
return { kind: "terminal", reason: "video-copy-cut-is-not-a-keyframe" };
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
//
|
|
232
|
-
//
|
|
231
|
+
// A transcoder needs the first audio packet at or after the cut to flush
|
|
232
|
+
// samples decoded from the packet before it. The output filter still trims
|
|
233
|
+
// that lookahead to the requested interval. Video and copied audio do not
|
|
234
|
+
// need a packet beyond the cut.
|
|
235
|
+
if (track.type === "audio" && mode === "transcode" && ordered) {
|
|
236
|
+
const trailing = packets.firstAtOrAfter(to);
|
|
237
|
+
if (trailing < packets.length) last = Math.max(last, trailing);
|
|
238
|
+
}
|
|
233
239
|
if (!track.complete && track.coveredThrough < to) {
|
|
234
240
|
return { kind: "needs-index", trackId, from: startAt, to };
|
|
235
241
|
}
|
|
@@ -37,6 +37,7 @@ export class SourcePreparation {
|
|
|
37
37
|
#failed;
|
|
38
38
|
#reprice;
|
|
39
39
|
#inputReady;
|
|
40
|
+
#sourceRestNeededFor;
|
|
40
41
|
#readyChanged;
|
|
41
42
|
#playbackAppliedFor;
|
|
42
43
|
#work = new Map();
|
|
@@ -47,7 +48,7 @@ export class SourcePreparation {
|
|
|
47
48
|
|
|
48
49
|
constructor({ viewers, candidatesFor, relatedFilesFor = () => [], priorityFor = (_viewer, priority) => priority,
|
|
49
50
|
inputReady = async () => false, readyChanged = () => {}, playbackAppliedFor = () => true,
|
|
50
|
-
inspect, withdraw, reprice = () => {}, failed }) {
|
|
51
|
+
sourceRestNeededFor = () => true, inspect, withdraw, reprice = () => {}, failed }) {
|
|
51
52
|
this.#viewers = viewers;
|
|
52
53
|
this.#candidates = candidatesFor;
|
|
53
54
|
this.#related = relatedFilesFor;
|
|
@@ -57,6 +58,7 @@ export class SourcePreparation {
|
|
|
57
58
|
this.#failed = failed;
|
|
58
59
|
this.#reprice = reprice;
|
|
59
60
|
this.#inputReady = inputReady;
|
|
61
|
+
this.#sourceRestNeededFor = sourceRestNeededFor;
|
|
60
62
|
this.#readyChanged = readyChanged;
|
|
61
63
|
this.#playbackAppliedFor = playbackAppliedFor;
|
|
62
64
|
}
|
|
@@ -83,6 +85,7 @@ export class SourcePreparation {
|
|
|
83
85
|
|
|
84
86
|
/** Current owners determine priority; old work never restores a withdrawn read. */
|
|
85
87
|
demandFor(work) {
|
|
88
|
+
if (work.role === "source-rest" && !this.#sourceRestNeededFor(work.sourceKey, work.fileIndex)) return null;
|
|
86
89
|
const handoffFileIndex = work.selected || (work.role === "source-rest" && work.ownerFileIndex === work.fileIndex)
|
|
87
90
|
? work.fileIndex : null;
|
|
88
91
|
const opening = Number.isInteger(handoffFileIndex) && this.#viewers.forSource(work.sourceKey).some(viewer =>
|