5

I am using plyr as wrapper around HTML5 video tag and using Hls.js to stream my .m3u8 video .

I was going around a lot of issues on plyr to enable quality selectors and came arounf multiple PR's which had this question but was closed saying the implementation is merged, till i came around this PR which says it's still open, but there was a custom implementation in the Comments which assured that it works . I was trying that implementation locally in order to check if we can add a quality selector but seems like i am missing something/ or the implementation dosent work .

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <title>HLS Demo</title>
      <link rel="stylesheet" href="https://cdn.plyr.io/3.5.10/plyr.css" />
      <style>
         body {
         max-width: 1024px;
         }
      </style>
   </head>
   <body>
      <video preload="none" id="player" autoplay controls crossorigin></video>
      <script src="https://cdn.plyr.io/3.5.10/plyr.js"></script>
      <script src="https://cdn.jsdelivr.net/hls.js/latest/hls.js"></script>
      <script>
         (function () {
          var video = document.querySelector('#player');
          var playerOptions= {
           quality: {
            default: '720',
            options: ['720']
           }
          };
          var player;
           player = new Plyr(video,playerOptions);
          if (Hls.isSupported()) {
           var hls = new Hls();
           hls.loadSource('https://content.jwplatform.com/manifests/vM7nH0Kl.m3u8');
             //hls.loadSource('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8');
          hls.attachMedia(video);
          hls.on(Hls.Events.MANIFEST_PARSED,function(event,data) {
  
 // uncomment to see data here 
//                     console.log('levels', hls.levels);  we get data here but not able to see in settings . 
          
           playerOptions.quality = {
            default: hls.levels[hls.levels.length - 1].height,
            options: hls.levels.map((level) => level.height),
            forced: true,
             // Manage quality changes
             onChange: (quality) => {
              console.log('changes',quality);
              hls.levels.forEach((level, levelIndex) => {
               if (level.height === quality) {
                hls.currentLevel = levelIndex;
               }
              });
             }
         };
        });
       }
         
          // Start HLS load on play event
          player.on('play', () => hls.startLoad());
         
          // Handle HLS quality changes
          player.on('qualitychange', () => {
           console.log('changed');
           if (player.currentTime !== 0) {
            hls.startLoad();
           }
          });
         })();
         
      </script>
   </body>
</html>

The above snippet works please run , but also if you uncomment the line in HLS Manifest you will see we get data in levels and also pass the data to player options but it dosent come up in settings.How can we add a quality selector to plyr when using Hls stream .

dingo_d
  • 11,160
  • 11
  • 73
  • 132
Rahul Singh
  • 19,030
  • 11
  • 64
  • 86

1 Answers1

6

I made a lengthy comment about this on github [1].

Working example: https://codepen.io/datlife/pen/dyGoEXo

The main idea to fix this is:

  • Configure Plyr options properly to allow the switching happen.
  • Let HLS perform the quality switching, not Plyr. Hence, we only need a single source tag in video tag.
<video>
  <source 
    type="application/x-mpegURL" 
    <!-- contain all the stream -->
    src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8">
</video>

[1] https://github.com/sampotts/plyr/issues/1741#issuecomment-640293554

Dat
  • 5,405
  • 2
  • 31
  • 32