fix(plex): a link too slow for the stream resumes in place, and says so
A request hls.js got no answer to in time (no status) was taken for a server away: a new session, the same first segment lost again, a restart every half minute that never ended, since every session answer reset the away window. Measured on prod: a work network at ~4 Mbit/s against 11-16 MB remux segments. A timeout now resumes loading in the same session; the away window ends only when media arrives (or a direct stream answers), and runs out in a 'too slow' error. A segment gets 30 s to its first byte. After 5 s of stalling on a link measured slower than the stream, the player says so with both rates.
This commit is contained in:
@@ -188,12 +188,18 @@ interface FragSample {
|
||||
type: string; // hls.js fragment type: "main" (video, and muxed audio) / "audio" / "subtitle"
|
||||
bytes: number;
|
||||
durationS: number; // MEDIA seconds the fragment carries (not how long it took to download)
|
||||
loading?: { start: number; end: number }; // when its download ran (ms), when hls.js knew
|
||||
}
|
||||
|
||||
export interface FragMeter {
|
||||
add(sample: FragSample): void;
|
||||
/** Bits per second of media, or undefined while nothing has been measured yet. */
|
||||
bitrate(): number | undefined;
|
||||
/** Bits per second the link delivered them at, or undefined while no download time is known: every
|
||||
* timed fragment's bytes over the time ANY of them was downloading. Not per type and summed like
|
||||
* `bitrate` — the renditions share one link, and their downloads overlap (measured: summing read
|
||||
* 2.3 Mbit/s through a 1.6 Mbit/s link). */
|
||||
arrival(): number | undefined;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
@@ -222,6 +228,22 @@ export function createFragMeter(window = 10): FragMeter {
|
||||
}
|
||||
return total > 0 ? total : undefined;
|
||||
},
|
||||
arrival() {
|
||||
const timed = [...byType.values()]
|
||||
.flat()
|
||||
.filter((f) => f.loading && f.loading.end > f.loading.start)
|
||||
.sort((a, b) => a.loading!.start - b.loading!.start);
|
||||
let busyMs = 0;
|
||||
let until = -Infinity;
|
||||
for (const { loading } of timed) {
|
||||
const { start, end } = loading!;
|
||||
if (end <= until) continue;
|
||||
busyMs += end - Math.max(start, until);
|
||||
until = end;
|
||||
}
|
||||
const bytes = timed.reduce((n, f) => n + f.bytes, 0);
|
||||
return busyMs > 0 ? (bytes * 8) / (busyMs / 1000) : undefined;
|
||||
},
|
||||
reset() {
|
||||
byType.clear();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user