@torrent-tv/proxy 2.107.20 → 2.107.21
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
|
@@ -589,6 +589,12 @@ export class EncodeRun {
|
|
|
589
589
|
producedSeconds: Math.max(0, this.progress.processedSeconds - this.progress.startPositionSeconds),
|
|
590
590
|
workingMs: this.clock.workingMs(at)
|
|
591
591
|
};
|
|
592
|
+
// A run can be admitted for exactly one segment. Establish its baseline
|
|
593
|
+
// on the first media progress report so closing that segment yields a
|
|
594
|
+
// processing rate without counting the preceding input wait.
|
|
595
|
+
if (this.#pieceSample === null && this.#workSample.producedSeconds > 0) {
|
|
596
|
+
this.#pieceSample = this.#workSample;
|
|
597
|
+
}
|
|
592
598
|
}
|
|
593
599
|
this.onProgress(this.progress.snapshot());
|
|
594
600
|
}
|
|
@@ -739,11 +745,10 @@ export class EncodeRun {
|
|
|
739
745
|
|
|
740
746
|
/**
|
|
741
747
|
* A closed piece is the moment this run's speed is read: what it made since
|
|
742
|
-
* the last reading, over its own working time.
|
|
743
|
-
*
|
|
744
|
-
* for its first input bytes
|
|
745
|
-
*
|
|
746
|
-
* and the next reading spans both.
|
|
748
|
+
* the last reading, over its own working time. The first baseline is the
|
|
749
|
+
* first positive progress report, so a one-piece run can be measured without
|
|
750
|
+
* charging the wait for its first input bytes as processing. A stretch with
|
|
751
|
+
* no progress keeps the earlier sample, and the next reading spans both.
|
|
747
752
|
*/
|
|
748
753
|
#measureSpeed() {
|
|
749
754
|
const sample = this.#workSample;
|
|
@@ -751,7 +756,7 @@ export class EncodeRun {
|
|
|
751
756
|
return;
|
|
752
757
|
}
|
|
753
758
|
if (this.#pieceSample === null) {
|
|
754
|
-
this.#pieceSample = sample;
|
|
759
|
+
if (sample.producedSeconds > 0) this.#pieceSample = sample;
|
|
755
760
|
return;
|
|
756
761
|
}
|
|
757
762
|
const speed = speedFromWork(this.#pieceSample, sample);
|
|
@@ -936,7 +936,7 @@ export class ViewerRequests {
|
|
|
936
936
|
const tracks = [];
|
|
937
937
|
for (const output of outputs) {
|
|
938
938
|
const trackProgress = output === session ? progress : this.#host.encodeRuns.progressOf(output);
|
|
939
|
-
const trackRates = this.#trackRateReadings(output, now
|
|
939
|
+
const trackRates = this.#trackRateReadings(output, now);
|
|
940
940
|
const trackName = output === session ? "video" : "audio";
|
|
941
941
|
// The page states the offset its player applied to this track, and the
|
|
942
942
|
// init it applied it to is the session's. Until both are known, the
|
|
@@ -1311,8 +1311,7 @@ export class ViewerRequests {
|
|
|
1311
1311
|
const id = typeof consumerId === "string" ? consumerId : "";
|
|
1312
1312
|
let state = byViewer.get(id);
|
|
1313
1313
|
if (!state) {
|
|
1314
|
-
state = { link: new this.#host.playbackReadiness.RateTrend(this.#host.lookaheadSeconds), sources: new Map()
|
|
1315
|
-
trackProgress: new WeakMap() };
|
|
1314
|
+
state = { link: new this.#host.playbackReadiness.RateTrend(this.#host.lookaheadSeconds), sources: new Map() };
|
|
1316
1315
|
byViewer.set(id, state);
|
|
1317
1316
|
}
|
|
1318
1317
|
return state;
|
|
@@ -1325,7 +1324,7 @@ export class ViewerRequests {
|
|
|
1325
1324
|
* runs of one output can report out of order, so a summary kept and added to
|
|
1326
1325
|
* would drop the later-told, earlier-taken one (torrent-tv/meta#178).
|
|
1327
1326
|
*/
|
|
1328
|
-
#trackRateReadings(output, now
|
|
1327
|
+
#trackRateReadings(output, now) {
|
|
1329
1328
|
const readings = (this.#host.encodeSpeedReadingsOf?.(output) ?? []).filter(reading => reading.at <= now);
|
|
1330
1329
|
const summary = readings.length > 0 ? this.#host.playbackReadiness.rateSummaryOf(readings) : null;
|
|
1331
1330
|
if (summary) return summary;
|
|
@@ -1340,21 +1339,9 @@ export class ViewerRequests {
|
|
|
1340
1339
|
seed.add(now, projected);
|
|
1341
1340
|
return seed.snapshot();
|
|
1342
1341
|
}
|
|
1343
|
-
//
|
|
1344
|
-
//
|
|
1345
|
-
//
|
|
1346
|
-
// inflate, the speed used by the forecast.
|
|
1347
|
-
if (output?.spec?.carries === "audio-only") {
|
|
1348
|
-
let trend = measurement.trackProgress.get(output);
|
|
1349
|
-
if (!trend) {
|
|
1350
|
-
trend = new this.#host.playbackReadiness.ProgressRate(
|
|
1351
|
-
this.#host.lookaheadSeconds,
|
|
1352
|
-
this.#host.segmentDurationSec
|
|
1353
|
-
);
|
|
1354
|
-
measurement.trackProgress.set(output, trend);
|
|
1355
|
-
}
|
|
1356
|
-
return trend.note(now, progress?.processedSeconds, progress?.startPositionSeconds);
|
|
1357
|
-
}
|
|
1342
|
+
// Progress over wall time includes source waits, which the forecast prices
|
|
1343
|
+
// separately. Keep the rate unknown until a measured or calibrated
|
|
1344
|
+
// processing rate exists; single-piece runs now publish their own rate.
|
|
1358
1345
|
return null;
|
|
1359
1346
|
}
|
|
1360
1347
|
|
|
@@ -72,7 +72,7 @@ import { ViewerRequests } from "./ViewerRequests.js";
|
|
|
72
72
|
import { OutputLifecycle } from "./OutputLifecycle.js";
|
|
73
73
|
import { SegmentServing } from "./SegmentServing.js";
|
|
74
74
|
import { audioStartSecondsFor } from "../viewer/audio-start.js";
|
|
75
|
-
import { forecastRate, rateSummaryOf, predictPlaybackReadiness,
|
|
75
|
+
import { forecastRate, rateSummaryOf, predictPlaybackReadiness, RateTrend } from "../viewer/playback-readiness.js";
|
|
76
76
|
import { audioRenditionName } from "../media/audio-inventory.js";
|
|
77
77
|
import { Renditions } from "../encode/Renditions.js";
|
|
78
78
|
import { CushionReport, LOOKAHEAD_PAUSE_SECONDS } from "../encode/CushionReport.js";
|
|
@@ -640,7 +640,7 @@ export function wireOutputs({
|
|
|
640
640
|
get encodeRuns() { return parts.encodeRuns; },
|
|
641
641
|
// When this viewer's playback can start and run to the end: the viewer
|
|
642
642
|
// component's forecast, which models the viewer's browser.
|
|
643
|
-
playbackReadiness: { predict: predictPlaybackReadiness, forecastRate, rateSummaryOf, RateTrend
|
|
643
|
+
playbackReadiness: { predict: predictPlaybackReadiness, forecastRate, rateSummaryOf, RateTrend },
|
|
644
644
|
// Whether the subtitle a viewer chose has been read where they stand — the
|
|
645
645
|
// source preparation's answer, set on these parts by the assembly.
|
|
646
646
|
subtitleReadyFor: (viewer) => parts.subtitleReadyFor?.(viewer) ?? true,
|
|
@@ -110,44 +110,6 @@ export class RateTrend {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/**
|
|
114
|
-
* Rates the media an output actually produced between progress reports.
|
|
115
|
-
* Unchanged progress keeps its original time, so a source wait is included
|
|
116
|
-
* instead of being mistaken for encoder throughput.
|
|
117
|
-
*/
|
|
118
|
-
export class ProgressRate {
|
|
119
|
-
#trend;
|
|
120
|
-
#horizonSeconds;
|
|
121
|
-
#adjacentRunSeconds;
|
|
122
|
-
#previous = null;
|
|
123
|
-
|
|
124
|
-
constructor(horizonSeconds, adjacentRunSeconds = 4) {
|
|
125
|
-
this.#horizonSeconds = horizonSeconds;
|
|
126
|
-
this.#adjacentRunSeconds = Number.isFinite(adjacentRunSeconds) && adjacentRunSeconds > 0
|
|
127
|
-
? adjacentRunSeconds
|
|
128
|
-
: 4;
|
|
129
|
-
this.#trend = new RateTrend(horizonSeconds);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
note(at, processedSeconds, startPositionSeconds) {
|
|
133
|
-
if (!Number.isFinite(at) || !Number.isFinite(processedSeconds)) return this.#trend.snapshot();
|
|
134
|
-
const start = Number.isFinite(startPositionSeconds) ? startPositionSeconds : 0;
|
|
135
|
-
const discontinuousStart = this.#previous && start !== this.#previous.start &&
|
|
136
|
-
(start < this.#previous.start || start > this.#previous.processedSeconds + this.#adjacentRunSeconds);
|
|
137
|
-
if (!this.#previous || discontinuousStart || processedSeconds < this.#previous.processedSeconds) {
|
|
138
|
-
this.#previous = { at, processedSeconds, start };
|
|
139
|
-
this.#trend = new RateTrend(this.#horizonSeconds);
|
|
140
|
-
return this.#trend.snapshot();
|
|
141
|
-
}
|
|
142
|
-
const elapsedMs = at - this.#previous.at;
|
|
143
|
-
if (processedSeconds > this.#previous.processedSeconds && elapsedMs > 0) {
|
|
144
|
-
this.#trend.add(at, (processedSeconds - this.#previous.processedSeconds) * 1000 / elapsedMs);
|
|
145
|
-
this.#previous = { at, processedSeconds, start };
|
|
146
|
-
}
|
|
147
|
-
return this.#trend.snapshot();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
113
|
/**
|
|
152
114
|
* @param {object} input
|
|
153
115
|
* @param {number} input.positionSeconds
|