Skip to content
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

Add the event FRAG_LOAD_PROGRESS removed on the v1 #4692

Open
korakore opened this issue May 13, 2022 · 2 comments
Open

Add the event FRAG_LOAD_PROGRESS removed on the v1 #4692

korakore opened this issue May 13, 2022 · 2 comments

Comments

@korakore
Copy link

Is your feature request related to a problem? Please describe.

With an older version of hls, I used to display a loader with a percent ton inform the user about the loading of the video. This loader is based on the event FRAG_LOAD_PROGRESS. Recently I started a migration ton hls.js 1.1.5 and I've seen the event doesn't exist anymore so the loader doesn't work.

Describe the solution you'd like

I would like a event FRAG_LOAD_PROGRESS triggered to get the current data and calculate the percent

Additional context

I will share a solution a found but I'm not sure at all this a good one...

I worked on the lib to add an new event :

image

And on xhr-loader I call to the callback onProgess in loadprogress() :

image

I had a condtion based on a param in the function to separate the process :

image

I had a condition in progressCallback() to trigger the new event :

image

@korakore korakore added Feature proposal Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels May 13, 2022
@robwalch robwalch added Wontdo and removed Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Jul 13, 2022
@robwalch
Copy link
Collaborator

Not a Contribution

You can use xhrSetup to attach progress event listeners to xhr objects. They are pretty inefficient and we removed the load progress event because of this and because of event ordering issues between modes of loading with the progressive set to true or false. There is not a clean way to tie this to a fragment or playlist object so there could be a feature request there.

The other thing is that the stats object on a fragment should not change between FRAG_LOADING and FRAG_LOADED, but it might be reassigned right after trigging the loading event. If that's the case file an issue. To track loading progress you just need to implement a timer to observe changes on the stats object between these events.

@posti85
Copy link

posti85 commented Jan 13, 2024

Based on:

To track loading progress you just need to implement a timer to observe changes on the stats object between these events.

I have done my own workarround. I will share it, it may help someone else. Test it setting browser network throttling to 'Fast 3G'.

const video = document.getElementById('video');
const hls = new Hls();

hls.on(Hls.Events.MEDIA_ATTACHED, () => {
  video.muted = true;
  video.play();
});

onLoadProgress(percentage => {
  console.log(percentage);
});

hls.loadSource('<video URL>');
hls.attachMedia(video);

function onLoadProgress(callback) {
  const progressPollingMs = 250;

  let currentFragStats;
  let alreadyLoaded;
  let isFirstLoad = true;

  hls.on(Hls.Events.FRAG_LOADING, (ev, data) => {
    currentFragStats = data.frag.stats;
    alreadyLoaded = 0;
    if (isFirstLoad) {
      isFirstLoad = false;
      reportProgress();
    }
  });

  hls.on(Hls.Events.ERROR, (ev, data) => {
    if (data.details === Hls.ErrorDetails.BUFFER_STALLED_ERROR) {
      alreadyLoaded = currentFragStats.loaded;
      reportProgress();
    }
  });

  function reportProgress() {
    function pollProgress() {
      const { loaded, total } = currentFragStats;
      if (total - alreadyLoaded > 0) {
        const percentage = Math.round(
          (loaded - alreadyLoaded) / (total - alreadyLoaded) * 100
        );
        callback(percentage);
      } else {
        callback(0);
      }
    }

    pollProgress();
    const intervalId = setInterval(pollProgress, progressPollingMs);

    hls.once(Hls.Events.FRAG_LOADED, () => {
      callback(100);
      clearInterval(intervalId);
    });
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants