-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I load a specific chunk/frag/segment OR all segments? #4745
Comments
related SO question with 500 bounty - https://stackoverflow.com/questions/72659255/hls-js-how-do-i-load-all-segments-chunks-for-a-video-especially-segments-befo |
STACKBLITZ TO DEMO THE PROBLEM https://stackblitz.com/edit/angular-ivy-pmu8py - EDIT https://angular-ivy-pmu8py.stackblitz.io/ - FULL SCREEN WITHOUT CODE Basically this proves that scrubbing backwards on lowest quality when all frags are loaded is as smooth as a baby's bottom (but NOT when all frags are NOT loaded as a result of dynamically switching quality level) |
Very interesting! You can get the list of fragments from any level event in The stream-controller(s) are only designed to load one segment at a time (stream-controller state is based on playlist fragment loading/parsing/appending state). Emitting the If going the undocumented/unsupported route is OK, you could tell the player what to load a fragment on This is a POC that shows you could force any arbitrary fragment to be loaded as long as another one is not already loading. I'll leave it to you to figure out which segment to load next. You can find what has been loaded already by looking at each fragment's stats, or (also private) hls.on('hlsFragBuffered', (name, event) => {
// You could also verify that `hls.streamController === 'idle'` here
const notLoadingAnotherFragment = event.frag === hls.streamController.fragCurrent;
if (notLoadingAnotherFragment) {
const levelDetails = hls.streamController.levels[hls.streamController.levelLastLoaded]?.details;
if (levelDetails) {
const frag = levelDetails.fragments[0]; // if stats show this is loaded grab the next one (or maybe start closest to fragCurrent and work backwards)
hls.streamController.loadFragment(frag, levelDetails, frag.start);
}
}
}); Be sure to adjust to buffer threshold and back buffer options so that segments are not flushed. Note that browsers have a quota on how much can be appended before appending will error. If your timeline is too long you are going to hit this error and could prevent the forward buffer from advancing as needed. This could be a nice way to solve #4553 without us adding wrapping target buffer time when loop is enabled on a media element. I don't however see a compelling way to support filling the back buffer automatically with quota limits being what they are. |
What do you want to do with Hls.js?
SHORT QUESTION (for those in a hurry)
With hls.js how do I load all or one segment/chunk/frag from the current level for a video?
QUESTION WITH BACKGROUND
I switch currentLevel with hls.js (via FlowPlayer) like so:
This is standard stuff and does an (almost) immediate level switch. The reason I am doing this is because I noticed that when scrubbing/seeking, the player is much more responsive when using a low quality level. When scrubbing/seeking starts I switch to the lowest available quality level and when it ends I then switch back to the highest quality level. My boss loves this.
One issue though, when I switch to low quality, lets assume the video currentTime is 30/60 seconds and the video has 5 chunks/segment. Hls.js will buffer the current chunk/segment (e.g. segment 3) and the next segments (e.g. segments 4 & 5) but it does not buffer earlier segments (e.g. segments 1 & 2) in the video. As a result, when scrubbing backwards, there's some jerking whilst unbuffered segments load on demand.
This is all great behaviour for normal playback, however the app I am building relies heavily on seeking.
Is there any way to force hls.js to buffer/load all chunks so as to avoid the jerking during segment loading? These segments/chunks are small and the videos are short so the time taken to load/buffer all the chunks should not be too much of a concern. Any help much appreciated. TIA
NB: I can see this behaviour via hooking into the FRAG_BUFFERED event and logging which chunks have just been buffered.
What have you tried so far?
Tried to manually load all chunks (without success):
But here startLoad does not start loading all chunks from 0secs onwards.
I even tried caching all the frags in an array when they first load and then reloading them later like so, but no success either, it does not seem to load any frags (note this is not an ideal solution since it would only work if chunks had previously been loaded, which may not be the case on a level switch):
Possibly, an alternative solution I've thought about is to write a custom fragment loader - but I have no idea how to do this and there are no examples - this latter approach seems quite complicated.
A workaround for this would be to use 2 players, one at the high level and one at the low level. And only show the relevant one. Using this approach all segments would be buffered. But I am trying to avoid this.
NOTE: docs say:
hls.currentLevel
set: Trigger an immediate quality level switch to new quality level. This will abort the current fragment request if any, flush the whole buffer, and fetch fragment matching with current position and requested quality level.
What I actually want it to do is:
Trigger an immediate quality level switch to new quality level. This will abort the current fragment request if any, flush the whole buffer, (I would prefer if it did not do this), and fetch ALL fragments (ideally in an intelligent order, e.g. current frag first) for requested quality level.
If I was able to load a chunk programatically I could manually load unbuffered chunks.
Alternatively, if hls.js allowed me to load all unbuffered chunks on a level switch, that would also suffice - either by means of an option or a command.
This seems like a reasonable use case and if this is not possible could this question be turned into a feature request. TIA.
The text was updated successfully, but these errors were encountered: