Allow latency compensator to be a little more aggressive

This commit is contained in:
Gabe Kangas
2022-03-27 14:44:50 -07:00
parent 44afc9c1ea
commit 78b0f7addc

View File

@@ -7,20 +7,22 @@ possible, without causing any buffering events.
It will: It will:
- Determine the start (max) and end (min) latency values. - Determine the start (max) and end (min) latency values.
- Keep an eye on download speed and stop compensating if it drops too low. - Keep an eye on download speed and stop compensating if it drops too low.
- Dynamically calculate the speedup rate based on network speed.
- Pause the compensation if buffering events occur. - Pause the compensation if buffering events occur.
- Completely give up on all compensation if too many buffering events occur. - Completely give up on all compensation if too many buffering events occur.
*/ */
const REBUFFER_EVENT_LIMIT = 5; // Max number of buffering events before we stop compensating for latency. const REBUFFER_EVENT_LIMIT = 5; // Max number of buffering events before we stop compensating for latency.
const MIN_BUFFER_DURATION = 300; // Min duration a buffer event must last to be counted. const MIN_BUFFER_DURATION = 500; // Min duration a buffer event must last to be counted.
const MAX_SPEEDUP_RATE = 1.08; // The playback rate when compensating for latency. const MAX_SPEEDUP_RATE = 1.08; // The playback rate when compensating for latency.
const TIMEOUT_DURATION = 20_000; // The amount of time we stop handling latency after certain events. const TIMEOUT_DURATION = 30 * 1000; // The amount of time we stop handling latency after certain events.
const CHECK_TIMER_INTERVAL = 5_000; // How often we check if we should be compensating for latency. const CHECK_TIMER_INTERVAL = 5_000; // How often we check if we should be compensating for latency.
const BUFFERING_AMNESTY_DURATION = 4 * 1000 * 60; // How often until a buffering event expires. const BUFFERING_AMNESTY_DURATION = 3 * 1000 * 60; // How often until a buffering event expires.
const HIGH_LATENCY_ENABLE_THRESHOLD = 20_000; // ms;
const LOW_LATENCY_DISABLE_THRESHOLD = 4500; // ms;
const REQUIRED_BANDWIDTH_RATIO = 2.0; // The player:bitrate ratio required to enable compensating for latency. const REQUIRED_BANDWIDTH_RATIO = 2.0; // The player:bitrate ratio required to enable compensating for latency.
const HIGHEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 2.4; // Segment length * this value is when we start compensating.
const LOWEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER = 1.7; // Segment length * this value is when we stop compensating.
const MIN_LATENCY = 4 * 1000; // The lowest we'll continue compensation to be running at.
const MAX_LATENCY = 8 * 1000; // The highest we'll allow a target latency to be before we start compensating.
class LatencyCompensator { class LatencyCompensator {
constructor(player) { constructor(player) {
this.player = player; this.player = player;
@@ -29,8 +31,6 @@ class LatencyCompensator {
this.inTimeout = false; this.inTimeout = false;
this.timeoutTimer = 0; this.timeoutTimer = 0;
this.checkTimer = 0; this.checkTimer = 0;
this.maxLatencyThreshold = 10000;
this.minLatencyThreshold = 8000;
this.bufferingCounter = 0; this.bufferingCounter = 0;
this.bufferingTimer = 0; this.bufferingTimer = 0;
this.playbackRate = 1.0; this.playbackRate = 1.0;
@@ -114,27 +114,37 @@ class LatencyCompensator {
} }
// How far away from live edge do we start the compensator. // How far away from live edge do we start the compensator.
this.maxLatencyThreshold = Math.min( const maxLatencyThreshold = Math.min(
segment.duration * 1000 * 4, MAX_LATENCY,
HIGH_LATENCY_ENABLE_THRESHOLD segment.duration * 1000 * HIGHEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER
); );
// How far away from live edge do we stop the compensator. // How far away from live edge do we stop the compensator.
this.minLatencyThreshold = Math.max( const minLatencyThreshold = Math.max(
segment.duration * 1000 * 2, MIN_LATENCY,
LOW_LATENCY_DISABLE_THRESHOLD segment.duration * 1000 * LOWEST_LATENCY_SEGMENT_LENGTH_MULTIPLIER
); );
const segmentTime = segment.dateTimeObject.getTime(); const segmentTime = segment.dateTimeObject.getTime();
const now = new Date().getTime(); const now = new Date().getTime();
const latency = now - segmentTime; const latency = now - segmentTime;
if (latency > this.maxLatencyThreshold) { console.log(
'latency',
latency / 1000,
'min',
minLatencyThreshold / 1000,
'max',
maxLatencyThreshold / 1000
);
if (latency > maxLatencyThreshold) {
this.start(proposedPlaybackRate); this.start(proposedPlaybackRate);
} else if (latency < this.minLatencyThreshold) { } else if (latency < minLatencyThreshold) {
this.stop(); this.stop();
} }
} catch (err) { } catch (err) {
console.warn(err); // console.warn(err);
} }
} }