@torrent-tv/proxy 2.97.22 → 2.97.23
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
|
@@ -123,6 +123,8 @@ export class EncodeRun {
|
|
|
123
123
|
*/
|
|
124
124
|
#pendingAtStop = null;
|
|
125
125
|
#closedTimings = new Map();
|
|
126
|
+
/** When the encoder named each closed piece on its channel, until it is published. */
|
|
127
|
+
#namedAt = new Map();
|
|
126
128
|
#publicationError = null;
|
|
127
129
|
#publicationCode = null;
|
|
128
130
|
#inputTruncated = false;
|
|
@@ -622,6 +624,7 @@ export class EncodeRun {
|
|
|
622
624
|
if (name.length === 0) {
|
|
623
625
|
continue;
|
|
624
626
|
}
|
|
627
|
+
this.#namedAt.set(name, this.now());
|
|
625
628
|
if (this.#publicationError) continue;
|
|
626
629
|
if (this.#stopping) {
|
|
627
630
|
// Flushed by our stop. Never published; it tells where the piece closed
|
|
@@ -681,7 +684,8 @@ export class EncodeRun {
|
|
|
681
684
|
// name a request can actually ask for.
|
|
682
685
|
let served;
|
|
683
686
|
try {
|
|
684
|
-
served = this.onClosed(name, following, this.#closedTimings.get(name) ?? null,
|
|
687
|
+
served = this.onClosed(name, following, this.#closedTimings.get(name) ?? null,
|
|
688
|
+
{ tentative, namedAt: this.#namedAt.get(name) ?? null });
|
|
685
689
|
} catch (error) {
|
|
686
690
|
if (quiet) {
|
|
687
691
|
// A piece closed before our stop that cannot be proved whole is not
|
|
@@ -702,7 +706,10 @@ export class EncodeRun {
|
|
|
702
706
|
} finally {
|
|
703
707
|
// A piece not proved whole on its own keeps its timing for the file
|
|
704
708
|
// after it.
|
|
705
|
-
if (!tentative || served)
|
|
709
|
+
if (!tentative || served) {
|
|
710
|
+
this.#closedTimings.delete(name);
|
|
711
|
+
this.#namedAt.delete(name);
|
|
712
|
+
}
|
|
706
713
|
}
|
|
707
714
|
|
|
708
715
|
if (!served) return false;
|
|
@@ -1121,7 +1121,7 @@ export class EncodeRuns {
|
|
|
1121
1121
|
// from it — a re-encoded picture, or sound served as its own output. Such
|
|
1122
1122
|
// a piece is published on its own line (torrent-tv/meta#178).
|
|
1123
1123
|
publishesAlone: this.publishesAlone(session),
|
|
1124
|
-
onClosed: (name, following, timing, { tentative = false } = {}) => {
|
|
1124
|
+
onClosed: (name, following, timing, { tentative = false, namedAt = null } = {}) => {
|
|
1125
1125
|
|
|
1126
1126
|
const index = session.segmentFormat.segmentIndexFromName(
|
|
1127
1127
|
session.segmentFormat.servedNameOf?.(name) ?? name);
|
|
@@ -1131,6 +1131,8 @@ export class EncodeRuns {
|
|
|
1131
1131
|
if (Number.isInteger(index) && (index < safeIndex || index > run.to)) return null;
|
|
1132
1132
|
let bytes = null;
|
|
1133
1133
|
const address = session.outputKey ?? "";
|
|
1134
|
+
// Read before anything rewrites it: when the encoder finished it.
|
|
1135
|
+
const writtenAt = this.#host.segmentFiles.writtenAtOf?.(address, name) ?? null;
|
|
1134
1136
|
const fmp4 = admittedInput && session.segmentFormat.id === "fmp4" && session.spec.carries !== "audio-only";
|
|
1135
1137
|
// The first piece of a run that read the picture from its keyframe:
|
|
1136
1138
|
// its leading pictures are the ones the run before made, or none.
|
|
@@ -1157,6 +1159,14 @@ export class EncodeRuns {
|
|
|
1157
1159
|
const published = this.#host.segmentFiles.publish(address, name, session.segmentFormat, { mediaRanges, bytes });
|
|
1158
1160
|
if (!published) throw new Error(`Closed piece #${index} could not be stored.`);
|
|
1159
1161
|
this.#leadingByOutput.get(address)?.delete(index);
|
|
1162
|
+
// WHERE A LATE PIECE'S TIME WENT: the encoder writing it, this process
|
|
1163
|
+
// getting to its name, or its publication waiting for the file after
|
|
1164
|
+
// it. A piece 5.7 s apart from the one before stopped a viewer inside a
|
|
1165
|
+
// running run, and nothing said which (torrent-tv/meta#178).
|
|
1166
|
+
const since = at => (Number.isFinite(at) ? `+${Math.round(at - run.startedAt)}ms` : "unknown");
|
|
1167
|
+
this.#host.logger.info(`encode-run #${run.from}..#${run.to} on ${address}: #${index} written by the encoder ${since(writtenAt)}, ` +
|
|
1168
|
+
`named ${since(namedAt)}, published ${since(run.now())} ` +
|
|
1169
|
+
(following ? `when ${following} closed` : tentative ? "on its own" : "at the run's end"));
|
|
1160
1170
|
return published;
|
|
1161
1171
|
|
|
1162
1172
|
},
|
|
@@ -594,6 +594,23 @@ export class SegmentStore {
|
|
|
594
594
|
return readFileSync(path.join(this.#root, directoryNameFor(key), makingName));
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
/**
|
|
598
|
+
* When the encoder last wrote a file it has closed under its working name,
|
|
599
|
+
* on the kernel's clock and so apart from when this process got to it; null
|
|
600
|
+
* when it is not there.
|
|
601
|
+
*
|
|
602
|
+
* @param {string} key
|
|
603
|
+
* @param {string} makingName
|
|
604
|
+
* @returns {number | null}
|
|
605
|
+
*/
|
|
606
|
+
writtenAtOf(key, makingName) {
|
|
607
|
+
try {
|
|
608
|
+
return statSync(path.join(this.#root, directoryNameFor(key), makingName)).mtimeMs;
|
|
609
|
+
} catch {
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
597
614
|
/**
|
|
598
615
|
* The media intervals a stored piece holds, read once from its bytes and kept
|
|
599
616
|
* with them, or undefined where its format reads none or it is not here.
|