diff --git a/src/core/stream/orchestrator/stream_orchestrator.ts b/src/core/stream/orchestrator/stream_orchestrator.ts index b2ffa609c0..eb42047f8d 100644 --- a/src/core/stream/orchestrator/stream_orchestrator.ts +++ b/src/core/stream/orchestrator/stream_orchestrator.ts @@ -108,7 +108,8 @@ export default function StreamOrchestrator( wantedBufferAhead, maxVideoBufferSize } = options; - const { MAXIMUM_MAX_BUFFER_AHEAD, + const { MINIMUM_MAX_BUFFER_AHEAD, + MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND } = config.getCurrent(); // Keep track of a unique BufferGarbageCollector created per @@ -116,12 +117,8 @@ export default function StreamOrchestrator( const garbageCollectors = new WeakMapMemory((segmentBuffer : SegmentBuffer) => { const { bufferType } = segmentBuffer; - const defaultMaxBehind = MAXIMUM_MAX_BUFFER_BEHIND[bufferType] != null ? - MAXIMUM_MAX_BUFFER_BEHIND[bufferType] as number : - Infinity; - const defaultMaxAhead = MAXIMUM_MAX_BUFFER_AHEAD[bufferType] != null ? - MAXIMUM_MAX_BUFFER_AHEAD[bufferType] as number : - Infinity; + const defaultMaxBehind = MAXIMUM_MAX_BUFFER_BEHIND[bufferType] ?? Infinity; + const maxAheadHigherBound = MAXIMUM_MAX_BUFFER_AHEAD[bufferType] ?? Infinity; return (gcCancelSignal : CancellationSignal) => { BufferGarbageCollector( { segmentBuffer, @@ -130,10 +127,11 @@ export default function StreamOrchestrator( (val) => Math.min(val, defaultMaxBehind), gcCancelSignal), - maxBufferAhead: createMappedReference(maxBufferAhead, - (val) => - Math.min(val, defaultMaxAhead), - gcCancelSignal) }, + maxBufferAhead: createMappedReference(maxBufferAhead, (val) => { + const lowerBound = Math.max(val, + MINIMUM_MAX_BUFFER_AHEAD[bufferType] ?? 0); + return Math.min(lowerBound, maxAheadHigherBound); + }, gcCancelSignal) }, gcCancelSignal ); }; diff --git a/src/default_config.ts b/src/default_config.ts index 2693d4b2f4..448e415159 100644 --- a/src/default_config.ts +++ b/src/default_config.ts @@ -201,6 +201,23 @@ const DEFAULT_CONFIG = { } as Partial>, /* eslint-enable @typescript-eslint/consistent-type-assertions */ + /* eslint-disable @typescript-eslint/consistent-type-assertions */ + /** + * Minimum possible buffer ahead for each type of buffer, to avoid Garbage + * Collecting too much data when it would have adverse effects. + * Equal to `0` if not defined here. + * @type {Object} + */ + MINIMUM_MAX_BUFFER_AHEAD: { + // Text segments are both much lighter on resources and might + // actually be much larger than other types of segments in terms + // of duration. Let's make an exception here by authorizing a + // larger text buffer ahead, to avoid unnecesarily reloading the + // same text track. + text: 2 * 60, + } as Partial>, + /* eslint-enable @typescript-eslint/consistent-type-assertions */ + /* eslint-disable @typescript-eslint/consistent-type-assertions */ /** * Maximum possible buffer behind for each type of buffer, to avoid too much