sampotts / plyr

A simple HTML5, YouTube and Vimeo player
https://plyr.io
MIT License
26.36k stars 2.92k forks source link

Quality switcher for HLS #1741

Open tolew1 opened 4 years ago

tolew1 commented 4 years ago

It appears that HLS quality switching is a highly requested feature and several other players seem to have this plugin. I see the ground work was laid with this commit/issue below. Is there any time frame to implement this feature? I think overall it's a great player and loads HLS videos faster for me than other open source players.

1607

lofcz commented 4 years ago

Upvoting, this is really a much need feature

Matho commented 4 years ago

Hi

We have implemented Plyr to our project, but have also found, that Plyr by default do not support multiple qualities for HLS. We needed it, so we tried to implement it.

The diff of our solution can be found at https://gist.github.com/Matho/b88d10da98471c114ca1a855882bbc85 It is not cleanest solution and a lot of work I have did in Ruby, because it was simple easier for me. Take this as the one of a way, or demonstration.

In ruby code, I'm downloading and parsing m3u8 file. Then, I'm extracting src links with quality information and passing to the html5 video element as various src elements. This should be done in javascript.

If you check the code in plyr.js.coffee, you can see how I switch the qualities. On quality change, I'm loading new file for HLS library. Because I know the seek time at that time, I set the seek time to be equal when playing new file. Thanks to it, I can continue with playing from the same point with different quality.

We have found bug, which is I think specific to our project. When I have activated the pip mode and changed the http url in browser, the pip video paused. So I have implemented the fix. It is the fix with browser_paused_pip variable.

I'm not saving quality to local storage (see storage option). Instead, I'm selecting the 'middle' quality as the default quality, when the player starts.

Maybe this will help you all. Maybe we will rewrite the m3u8 parsing to JS one day. Or maybe somebody will help me with this step?

Thanks and have a nice day

tca3 commented 4 years ago

Hello folks, here's our solution in TS - it basically uses the levels parsed from the manifest and adds each quality automatically, hope it helps anyone:


this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
  this.player = this.loadPlayer();
});

loadPlayer() {
  const playerOptions = {
    quality: {
      default: '720',
      options: ['720']
    }
  };

  // If HLS is supported (ie non-mobile), we add video quality settings
  if (Hls.isSupported()) {
    playerOptions.quality = {
    default: this.hls.levels[this.hls.levels.length - 1].height,
    options: this.hls.levels.map((level) => level.height),
    forced: true,
    // Manage quality changes
    onChange: (quality: number) => {
      this.hls.levels.forEach((level, levelIndex) => {
          if (level.height === quality) {
            this.hls.currentLevel = levelIndex;
          }
        });
      }
    };
  }

  this.player = new Plyr(this.videoElement.nativeElement, playerOptions);

  // Start HLS load on play event
  this.player.on('play', () => this.hls.startLoad());

  // Handle HLS quality changes
  this.player.on('qualitychange', () => {
    if (this.player.currentTime !== 0) {
      this.hls.startLoad();
    }
  });

  return this.player;
}
Matho commented 4 years ago

Hi @ThomasCantonnet Many thanks for sharing your code! I did the parsing in Ruby, now I can rewrite the app to do it with hls.js

soheil commented 4 years ago

Is there another issue keeping track of this or is this the canonical place for this feature?

okxaas commented 4 years ago

Add the following code in the <head>

<script src="https://cdn.plyr.io/3.5.10/plyr.polyfilled.js"></script>
<script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.10/plyr.css" />

Add the following code in the Githubissues.

  • Githubissues is a development platform for aggregating issues.