video-dev / hls.js

HLS.js is a JavaScript library that plays HLS in browsers with support for MSE.
https://hlsjs.video-dev.org/demo
Other
14.93k stars 2.59k forks source link

BackBuffer Memory Issues #3256

Closed Faizranas closed 3 years ago

Faizranas commented 3 years ago

What do you want to do with Hls.js? I am facing memory issue on low end device. I tried liveBackBufferLength=0 which is working perfectly fine to clear back buffer data and It is releasing memory in the case of Live Stream data but the same property is not working with non live stream data. It is not evicting memory, The memory continues growing. Is there any other option to release back buffer data for normal stream?

What have you tried so far? I have used liveBackBufferLength=0 which works fine for live stream. I don't see any other option to evict memory for normal stream. Please suggest how to evict back buffer data of a normal stream to improve experience.

robwalch commented 3 years ago

Hi @Faizranas,

Can you provide more information about the device and how to reproduce the memory issues?

It's really the browsers responsibility to evict media from the MediaSource back buffer, so which OS/Browser and any open-issues against them would also help.

We have an open issue for clearing metadata cue points (we should include subtitle cues as well) #1975 on BUFFER_FLUSHING, but I don't think we have a formal feature request for setting / maintaining back buffer length with VOD playback.

It's a shame liveBackBufferLength isn't simply backBufferLength. I much rather have a single setting and flow for managing the back buffer, but I'm not sure that would work for everyone.

For now, I'm fairly certain that if you want to manually remove parts of the buffer you can by triggering BUFFER_FLUSHING. I would be a little more generous about leaving some room for keyframes (at least 1-2 TARGET_DURATIONs) and the ability to skip back by small amounts (liveBackBufferLength=0 is extreme and probably worked around to an extent to prevent playback from stalling/errorring):

// call this on `FRAG_CHANGED` to maintain a small back buffer in VOD streams:
hls.trigger(Event.BUFFER_FLUSHING, { startOffset: 0, endOffset: media.currentTime - 15 });
Faizranas commented 3 years ago

Thank you very much Rob Walch for your response. We have low end feature phone device on KaiOS/Firefox OS platform. It has total 500 Mb RAM where an app gets approx. 100-120 Mb to run video on 320*240 resolution. We are providing low bandwidth and resolution stream to our video player to avoid lagging and smooth experience. Everything is working as expected when we configured liveBackBufferLength=0 for a live stream, the memory unique to the process is getting free when media buffer gets evicted. As per our observation the memory is continuously increasing in VOD playback case.

The suggested approach hls.trigger(Event.BUFFER_FLUSHING, { startOffset: 0, endOffset: media.currentTime - 15 }); for VOD is working but observed frequent stalling error. We will test it thoroughly.

I think that HLS is keeping back buffer data in memory intentionally for smooth previous frame playback experience. Please clarify following points and let me know If I am wrong.

robwalch commented 3 years ago

Will it work properly in live & VOD both cases if we fix the fragment details runtime live property value form this._live = details.live; to this._live = true; I think that It should also resolve our back buffer memory issue in VOD case.

Work properly how? Not stalling? As I mentioned, if you delete the part of the buffer that is playing, playback will stall. Try not to do that. You should not change VOD to live at runtime. That is likely to cause negative side-effects (like reloading of playlists).

Will the entire previous buffer get evicted from memory if we switch the bandwidth of any running stream?

Setting hls.currentLevel clears the buffer before loading the new level. Setting nextLevelonly clears the buffer after the end of the currently playing fragment. Setting loadLevel does not clear the buffer. You can see this behavior in the demo page with the timeline and quality-levels tabs open:

setting-current-level

Faizranas commented 3 years ago

Thank you very much Rob Walch for your suggestions.

whatever1211 commented 3 years ago

Thank you @robwalch, I was running on version 0.12.4 and haven't had backBufferLength atrribute yet. Your solution save my code. No need to reduce maxBufferLength for the sake of playable anymore.