index.html 6.71 KB
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>video.js HLS Stats</title>

  <link href="../../node_modules/video.js/dist/video-js.css" rel="stylesheet">

  <!-- video.js -->
  <script src="../../node_modules/video.js/dist/video.js"></script>

  <!-- transmuxing -->
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/stream.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/mp4-generator.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/transmuxer.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/flv-tag.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/exp-golomb.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/h264-extradata.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/h264-stream.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/aac-stream.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/metadata-stream.js"></script>
  <script src="../../node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/segment-parser.js"></script>

  <!-- Media Sources plugin -->
  <script src="../../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>

  <!-- HLS plugin -->
  <script src="../../src/videojs-hls.js"></script>

  <!-- m3u8 handling -->
  <script src="../../src/xhr.js"></script>
  <script src="../../src/stream.js"></script>
  <script src="../../src/m3u8/m3u8-parser.js"></script>
  <script src="../../src/playlist.js"></script>
  <script src="../../src/playlist-loader.js"></script>

  <script src="../../node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
  <script src="../../src/decrypter.js"></script>

  <!-- player stats visualization -->
  <link href="stats.css" rel="stylesheet">
  <script src="../switcher/js/vendor/d3.min.js"></script>

  <!-- debugging -->
  <script src="../../src/bin-utils.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
    }
    .info {
      background-color: #eee;
      border: thin solid #333;
      border-radius: 3px;
      padding: 0 5px;
      margin: 20px 0;
    }
  </style>

</head>
<body>
  <div class="info">
    <p>The video below is an <a href="https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-SW1">HTTP Live Stream</a>. On desktop browsers other than Safari, the HLS plugin will polyfill support for the format on top of the video.js Flash tech.</p>
    <p>Due to security restrictions in Flash, you will have to load this page over HTTP(S) to see the example in action.</p>
  </div>
  <video id="video"
         class="video-js vjs-default-skin"
         height="300"
         width="600"
         controls>
    <source
       src="http://solutions.brightcove.com/jwhisenant/hls/apple/bipbop/bipbopall.m3u8"
       type="application/x-mpegURL">
    <source
       src="http://s3.amazonaws.com/_bc_dml/example-content/bipbop-id3/index.m3u8"
       type="application/x-mpegURL">
  </video>
  <section class="stats">
    <h2>Player Stats</h2>
    <div class="segment-timeline"></div>
    <dl>
      <dt>Current Time:</dt>
      <dd class="current-time-stat">0</dd>
      <dt>Buffered:</dt>
      <dd><span class="buffered-start-stat">-</span> - <span class="buffered-end-stat">-</span></dd>
      <dt>Seekable:</dt>
      <dd><span class="seekable-start-stat">-</span> - <span class="seekable-end-stat">-</span></dd>
      <dt>Video Bitrate:</dt>
      <dd class="video-bitrate-stat">0 kbps</dd>
      <dt>Measured Bitrate:</dt>
      <dd class="measured-bitrate-stat">0 kbps</dd>
    </dl>
    <div class="switching-stats">
      Once the player begins loading, you'll see information about the
      operation of the adaptive quality switching here.
    </div>
  </section>

  <script src="stats.js"></script>
  <script>
    videojs.options.flash.swf = '../../node_modules/videojs-swf/dist/video-js.swf';
    // initialize the player
    var player = videojs('video');

    // ------------
    // Player Stats
    // ------------

    var currentTimeStat = document.querySelector('.current-time-stat');
    var bufferedStartStat = document.querySelector('.buffered-start-stat');
    var bufferedEndStat = document.querySelector('.buffered-end-stat');
    var seekableStartStat = document.querySelector('.seekable-start-stat');
    var seekableEndStat = document.querySelector('.seekable-end-stat');
    var videoBitrateState = document.querySelector('.video-bitrate-stat');
    var measuredBitrateStat = document.querySelector('.measured-bitrate-stat');

    player.on('timeupdate', function() {
      currentTimeStat.textContent = player.currentTime().toFixed(1);
    });

    player.on('progress', function() {
      var oldStart, oldEnd;
      // buffered
      var buffered = player.buffered();
      if (buffered.length) {

        oldStart = bufferedStartStat.textContent;
        if (buffered.start(0).toFixed(1) !== oldStart) {
          bufferedStartStat.textContent = buffered.start(0).toFixed(1);
        }
        oldEnd = bufferedEndStat.textContent;
        if (buffered.end(0).toFixed(1) !== oldEnd) {
          bufferedEndStat.textContent = buffered.end(0).toFixed(1);
        }
      }

      // seekable
      var seekable = player.seekable();
      if (seekable && seekable.length) {

        oldStart = seekableStartStat.textContent;
        if (seekable.start(0).toFixed(1) !== oldStart) {
          seekableStartStat.textContent = seekable.start(0).toFixed(1);
        }
        oldEnd = seekableEndStat.textContent;
        if (seekable.end(0).toFixed(1) !== oldEnd) {
          seekableEndStat.textContent = seekable.end(0).toFixed(1);
        }
      }

      // bitrates
      var playlist = player.tech.hls.playlists.media();
      if (playlist && playlist.attributes && playlist.attributes.BANDWIDTH) {
        videoBitrateState.textContent = (playlist.attributes.BANDWIDTH / 1024).toLocaleString(undefined, {
          maximumFractionDigits: 1
        }) + ' kbps';
      }
      if (player.tech.hls.bandwidth) {
        measuredBitrateStat.textContent = (player.tech.hls.bandwidth / 1024).toLocaleString(undefined, {
          maximumFractionDigits: 1
        }) + ' kbps';
      }
    });

    videojs.Hls.displayStats(document.querySelector('.switching-stats'), player);
    videojs.Hls.displayCues(document.querySelector('.segment-timeline'), player);
  </script>
</body>
</html>