Skip to content

Conversation

hongjun-bae
Copy link
Collaborator

@hongjun-bae hongjun-bae commented May 27, 2025

This PR will...

This PR introduces a new configuration option, preserveManualLevelOnError. When this option is set to true, hls.js will maintain the manually selected quality level even if network errors (such as FRAG_LOAD_ERROR, FRAG_LOAD_TIMEOUT, KEY_LOAD_ERROR, or KEY_LOAD_TIMEOUT) occur. If set to false (the default behavior), hls.js will switch back to auto level selection mode (loadLevel = -1) upon encountering such errors, attempting to find a rendition that can be loaded successfully.

Why is this Pull Request needed?

Currently, when a user manually selects a specific quality level, hls.js defaults to switching back to automatic level selection if it encounters fragment loading or key loading errors. This behavior can be undesirable for users on unstable internet connections who prefer to remain on their chosen quality level, even if it means experiencing more retries or buffering, rather than having the player automatically switch to a different (often lower) quality. Furthermore, some users may wish to maintain their current quality setting even when facing playback errors, considering it the player developer's responsibility to resolve such issues rather than defaulting to a quality switch.

Services using hls.js may not always offer or want to provide automatic quality selection depending on the situation. Furthermore, they might prefer to implement different fallback mechanisms, making the current forced switch to auto quality in the player less ideal.

As discussed in issue #7221, developers previously had to implement workarounds by manually resetting autoLevelCapping and minAutoBitrate on error events to achieve the desired behavior. This new preserveManualLevelOnError flag provides a simpler and more direct way to control this behavior.

Are there any points in the code the reviewer needs to double check?

  • The logic within the getLevelSwitchAction method in src/controller/error-controller.ts should be reviewed to ensure it correctly respects the preserveManualLevelOnError flag when hls.autoLevelEnabled is false.
  • The default value for preserveManualLevelOnError in src/config.ts is set to false to maintain existing default behavior.
  • Ensure the API documentation update in api-extractor/report/hls.js.api.md correctly reflects the new configuration option.

Resolves issues:

Checklist

  • changes have been done against master branch, and PR does not conflict
  • new unit / functional tests have been added (whenever applicable)
  • API or design changes are documented in API.md

@vkaswin
Copy link

vkaswin commented May 27, 2025

Hi @robwalch ,

My concern is that once the player switches to autoLevel due to a fragment error, HLS.js not loading the level that fragment error occurs.

For example, if the manifest includes levels for 1080p, 720p, 480p, and 180p, and a 1080p fragment returns a 404 error, the player switches to 720p with autoLevel enabled. However, it never switches back to 1080p even when network conditions improve.

The same happens if a 720p fragment fails it switches to 480p and stays there. Eventually, if a 480p fragment also fails, the player falls back to 180p and continues to load only that lower quality stream.

If any one of the fragments returns a 404 error in 1080p level, why HLS.js doesn't switch back to a 1080p level after some time when auto level is enabled?

Upon checking, I noticed that the getEstimate() method consistently returns a bitrate lower than the bitrate of the level where the last fragment error occurred. As a result, the player never level up, even if the network is good.

I believe the new config preserveManualLevelOnError does not resolve my issue. My concern is specifically about the player to recover higher levels after fragment errors when autoLevel is in use.

@robwalch
Copy link
Collaborator

My concern is that once the player switches to autoLevel due to a fragment error, HLS.js not loading the level that fragment error occurs.

If any one of the fragments returns a 404 error in 1080p level, why HLS.js doesn't switch back to a 1080p level after some time when auto level is enabled?

These comments should be included in #7074 if they have not already.

Upon checking, I noticed that the getEstimate() method consistently returns a bitrate lower than the bitrate of the level where the last fragment error occurred. As a result, the player never level up, even if the network is good.

If the connection is not delivering media at a high bitrate, that is not good enough to switch back up.

If the connection really is good, and fragment errors stop, then the average will go back up.

I believe the new config preserveManualLevelOnError does not resolve my issue. My concern is specifically about the player to recover higher levels after fragment errors when autoLevel is in use.

Then this PR will not resolve #7074. The feature this PR adds is only for maintaining a manual selection even when it faults playback.

Clearing Level.fragmentError counts after some period of stable playback, and easing any penalties on error, may be the best path forward for #7074.

@vkaswin
Copy link

vkaswin commented May 27, 2025

Clearing Level.fragmentError counts after some period of stable playback, and easing any penalties on error, may be the best path forward for #7074.

Will this be handled in the upcoming updates? @robwalch

@hongjun-bae
Copy link
Collaborator Author

Yes, as robwalch said, this PR is not meant to resolve issue 7074, but is intended to address issue 7221 by maintaining the manual selection even when a playback error occurs.

@hongjun-bae
Copy link
Collaborator Author

@robwalch could you please let me know which version this PR is expected to be included in? Also, could you provide an estimated release schedule?

@robwalch robwalch added this to the 1.6.3 milestone May 28, 2025
@robwalch robwalch merged commit 07fcc6d into video-dev:master May 28, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

disable autoLevel completely
3 participants