Hls.js: Change the src of the video only when the content has loaded

Created on 19 Jan 2021  路  6Comments  路  Source: video-dev/hls.js

What do you want to do with Hls.js?
Hi, I want to update the src of a video player only when this component has loaded some .m3u8 and .ts files to show to the user.

What have you tried so far?
Actually my player can play a live stream and when this live is off it can play a fallback/callback video. But there's a problem in the user experience. When the live stream starts and the src of the video changes back to the live stream it displays a black screen that only disappears when the chunkies of the live has been loaded.

I want to know if there's a correct order to put the events in Hls so that this problem is minimized. I've tried only 2 options but don't know if this is the correct approach. My strategies are:

hls = new Hls(config);
// first loads the content
hls.loadSource(src);

// then attach the video element to reproduce the media
hls.on(Hls.Events.MANIFEST_PARSED, () => {
  hls.attachMedia(videoElement);
});

// then plays the video
...

And the other flux I've tested is:

hls = new Hls(config);
// first attachs the video element
hls.attachMedia(videoElement);

// then loads the video (live stream)
hls.on(Hls.Events.MEDIA_ATTACHED, () => {
  hls.loadSource(src);
});

// then plays the video
...

Consider that the Hls will only be instanciated when the live stream is responding with a success status code, so the live stream is working correctly and the chunkies can be downloaded.

answered

All 6 comments

I think that had solved this problem, but don't know exactly how. So if anyone can help me interpret this it would be great.

My idea is this:

// control variable
let firstFragLoaded = false;

hls = new Hls(config);

// starts loading the video src
hls.loadSource(src);

// i don't know very much about this event
// but in my tests it is triggered when a ".ts" has been loaded
// so the video has content to show
hls.on(Hls.Events.LEVEL_LOADED , (event, data) => {
  if (!firstFragLoaded) {
    hls.attachMedia(videoElement)
  }
  firstFragLoaded = true;
});

Like I said in the comments of the code I don't understand some things about this event LEVEL_LOADED but apparently it is triggered when there is a ".ts" file ready to be played by the video element. I this case I need to use this control variable because this event is triggered many times but the hls just need to attach the videoElement in the first time.

Recently I've read the docs, maybe later I'll read it again. Now if anyone could explain this event in more details or recommend other event with a similar behavior would be great.

Hi @64J0,

LEVEL_LOADED is triggered after an HLS rendition (#EXT-X-STREAM-INF) is loaded. This would be prior to loading any segment since this the file (playlist) that contains the list of segments.

Note that loadSource is the thing that starts the loading of files. So you won't get any _LOADED events without first passing an m3u8 URL to loadSource.

Alright @robwalch , only to confirm if I understood. As you said this LEVEL_LOADED event will be triggered when the hls instance gets the .m3u8 stream src and finished loading the playlist. The loaded data will tell the hls the URL to the next chunk of the stream to be loaded (with something like #EXTINF:16.666, media-up9z6xg5e_b915536_1.ts), right?

But actually in this time it won't have loaded any .ts file to show to the user, it will only know the URL to request this chunk. Is this right?

Sounds right. An HLS stream can have multiple quality levels, LEVEL_LOADED is fired after a level is loaded. So it would not have loaded any TS files when the first LEVEL_LOADED event is fired, but the level can change, resulting in a different level loading afterward.

Alright, thanks for your help @robwalch , now I'll close the issue. Have a good day.

Was this page helpful?
0 / 5 - 0 ratings