@torrent-tv/proxy 2.107.45 → 2.107.46
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
|
@@ -521,7 +521,7 @@ export function predictPlaybackReadiness(input = {}) {
|
|
|
521
521
|
}));
|
|
522
522
|
const sourceByteCoverage = new Map([...sourceByteService].map(([id, ranges]) => [id, numericCoverage(ranges)]));
|
|
523
523
|
const sourceArrivals = new Map([...sourceByteService].map(([id, ranges]) => [id, indexedArrivals(ranges)]));
|
|
524
|
-
|
|
524
|
+
const transferJobs = [];
|
|
525
525
|
const completions = [];
|
|
526
526
|
const productions = [];
|
|
527
527
|
for (const job of jobs) {
|
|
@@ -609,9 +609,17 @@ export function predictPlaybackReadiness(input = {}) {
|
|
|
609
609
|
const sourcePlanned = sourceArrivalAt > 0 && plan.finish >= sourceArrivalAt;
|
|
610
610
|
productions.push({ at: producedAt, trackIndex, segment, requiresSource: sourceArrivalAt > 0, sourceArrivalAt,
|
|
611
611
|
sourcePlanned, runAdmissionAt, runOpenSeconds, productionStartAt, encodeWork });
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
612
|
+
transferJobs.push({ trackIndex, segment, sizeBits, readyAt: producedAt, sourceArrivalAt, sourcePlanned,
|
|
613
|
+
order: transferJobs.length, appendSeconds: finiteNonNegative(track.appendSeconds) });
|
|
614
|
+
}
|
|
615
|
+
// A transfer waits only for work that is ready on its own stream and for
|
|
616
|
+
// bytes already being served by the shared link. A video piece whose encode
|
|
617
|
+
// is still running cannot reserve link time ahead of a ready audio piece.
|
|
618
|
+
// Each stream remains ordered; the single link remains shared.
|
|
619
|
+
const transfers = scheduleTransfers(transferJobs, link);
|
|
620
|
+
const transferFinish = transfers.reduce((finish, transfer) => Math.max(finish, transfer.deliveryAt), 0);
|
|
621
|
+
for (const transfer of transfers) {
|
|
622
|
+
const { trackIndex, segment, deliveryAt, appendSeconds, sourceArrivalAt, sourcePlanned } = transfer;
|
|
615
623
|
completions.push({ at: deliveryAt + appendSeconds, deliveryAt, appendSeconds, trackIndex, segment, sourceArrivalAt,
|
|
616
624
|
sourcePlanned });
|
|
617
625
|
}
|
|
@@ -780,6 +788,48 @@ function isPiece(segment) {
|
|
|
780
788
|
Number.isFinite(segment?.endSeconds) && segment.endSeconds > segment.startSeconds;
|
|
781
789
|
}
|
|
782
790
|
|
|
791
|
+
/**
|
|
792
|
+
* Serve each stream's fragments in order on one shared link, starting the
|
|
793
|
+
* earliest released fragment whenever the link becomes free.
|
|
794
|
+
*
|
|
795
|
+
* @param {Array<{ trackIndex: number, segment: object, sizeBits: number, readyAt: number,
|
|
796
|
+
* order: number, appendSeconds: number }>} jobs
|
|
797
|
+
* @param {{ finish: (bits: number, startAt: number) => number }} link
|
|
798
|
+
*/
|
|
799
|
+
function scheduleTransfers(jobs, link) {
|
|
800
|
+
const queues = new Map();
|
|
801
|
+
for (const job of jobs) {
|
|
802
|
+
const queue = queues.get(job.trackIndex) ?? [];
|
|
803
|
+
queue.push(job);
|
|
804
|
+
queues.set(job.trackIndex, queue);
|
|
805
|
+
}
|
|
806
|
+
const served = new Map();
|
|
807
|
+
const trackFreeAt = new Map();
|
|
808
|
+
const transfers = [];
|
|
809
|
+
let linkFreeAt = 0;
|
|
810
|
+
while (transfers.length < jobs.length) {
|
|
811
|
+
let selected = null;
|
|
812
|
+
let selectedReadyAt = Number.POSITIVE_INFINITY;
|
|
813
|
+
for (const [trackIndex, queue] of queues) {
|
|
814
|
+
const nextIndex = served.get(trackIndex) ?? 0;
|
|
815
|
+
const job = queue[nextIndex];
|
|
816
|
+
if (!job) continue;
|
|
817
|
+
const readyAt = Math.max(job.readyAt, trackFreeAt.get(trackIndex) ?? 0);
|
|
818
|
+
if (readyAt < selectedReadyAt || readyAt === selectedReadyAt && (selected === null || job.order < selected.order)) {
|
|
819
|
+
selected = job;
|
|
820
|
+
selectedReadyAt = readyAt;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
if (!selected) break;
|
|
824
|
+
const deliveryAt = link.finish(selected.sizeBits, Math.max(linkFreeAt, selectedReadyAt));
|
|
825
|
+
transfers.push({ ...selected, deliveryAt });
|
|
826
|
+
served.set(selected.trackIndex, (served.get(selected.trackIndex) ?? 0) + 1);
|
|
827
|
+
trackFreeAt.set(selected.trackIndex, deliveryAt);
|
|
828
|
+
linkFreeAt = deliveryAt;
|
|
829
|
+
}
|
|
830
|
+
return transfers;
|
|
831
|
+
}
|
|
832
|
+
|
|
783
833
|
/**
|
|
784
834
|
* A duration-level estimate of the suffix after the exact near window. Source
|
|
785
835
|
* work uses each file's aggregate byte density and measured download service;
|