chromium/media/test/data/eme_player.html

<!DOCTYPE html>
<html lang='en-US'>
  <head>
    <title>EME playback test application</title>
  </head>
  <body style='font-family:"Lucida Console", Monaco, monospace; font-size:14px' onload="start()">
    <i>Clearkey works only with content encrypted using bear key.</i><br><br>
    <table>
    <tr title='URL param mediaFile=...'>
      <td><label for='mediaFile'>Encrypted video URL:</label></td>
      <td><input id='mediaFile' type='text' size='64'></td>
    </tr>
    <tr title='URL param licenseServerURL=...'>
      <td><label for='licenseServer'>License sever URL:</label></td>
      <td><input id='licenseServer' type='text' size='64'></td>
    </tr>
    <tr title='URL param keySystem=...'>
      <td><label for='keySystemList'>Key system:</label></td>
      <td><select id='keySystemList'></select></td>
    </tr>
    <tr title='URL param mediaType=...'>
      <td><label for='mediaTypeList'>Media type:</label></td>
      <td><select id='mediaTypeList'></select></td>
    </tr>
    <tr title='URL param useMSE=1|0'>
      <td><label for='useMSE'>Load media by:</label></td>
      <td>
        <select id='useMSE'>
          <option value='true' selected='selected'>MSE</option>
          <option value='false'>src</option>
        </select>
      </td>
    </tr>
    </table>
    <br>
    <button onclick='start();'>Play</button>
    <br><br>
    Decoded fps: <span id='decodedFPS'></span>
    <br>
    Dropped fps: <span id='droppedFPS'></span>
    <br>
    Total dropped frames: <span id='droppedFrames'></span>
    <br><br>
    <table>
    <tr>
      <td valign='top'><span id='video'></span></td>
      <td valign='top'>
        <label for='logs' onclick="toggleDisplay('logs');"><i>Click to toggle logs visibility (newest at top).</i><br></label>
        <div id='logs' style='overflow: auto; height: 480px; width: 480px; white-space: nowrap; display: none'></div>
      </td>
    </tr>
    </table>
    <div></div>
  </body>
  <script src='eme_player_js/app_loader.js' type='text/javascript'></script>
  <script type='text/javascript'>
    var testConfig;
    var emeApp;
    var player;
    var heartbeatCount = 0;

    function getTimeRanges(range) {
      const result = [];
      for (let i = 0; i < range.length; i++) {
        result.push(`[${range.start(i)},${range.end(i)}]`);
      }
      return '[' + result.join(', ') + ']';
    }

    function getVideoStatus(video) {
      if (video == null) {
        return 'null';
      }
      const result = [];
      result.push(`paused: ${video.paused}`);
      result.push(`ended: ${video.ended}`);
      result.push(`currentTime: ${video.currentTime}`);
      result.push(`duration: ${video.duration}`);
      result.push(`buffered: ${getTimeRanges(video.buffered)}`);
      result.push(`played: ${getTimeRanges(video.played)}`);
      if (video.error) {
        result.push(`error: {${video.error.code},${video.error.message}}`);
      }
      return result.join(', ');
    }

    function initApp() {
      testConfig = new TestConfig();
      testConfig.loadQueryParams();
      // Update document with test configuration values.
      emeApp = new EMEApp(testConfig);
      setInterval(function () {
                      Utils.timeLog('heartbeat #' + ++heartbeatCount +
                                    ' video: ' + getVideoStatus(player.video));
                  }, 1000);
    }

    function onTimeUpdate(e) {
      var video = e.target;
      Utils.timeLog('timeupdate @ ' + video.currentTime);
      if (video.currentTime < 1)
        return;

      Utils.timeLog('waiting for video to end.');
      video.removeEventListener('ended', Utils.failTest);
      Utils.installTitleEventHandler(video, 'ended');
      video.removeEventListener('timeupdate', onTimeUpdate);
    }

    function onFirstPlayEnded(e) {
      Utils.timeLog('First play ended.');
      var video = e.target;
      video.removeEventListener('ended', onFirstPlayEnded);
      video.removeEventListener('abort', Utils.failTest);

      // Reset src (to same video again).
      PlayerUtils.setVideoSource(player);

      // Play the video a second time.
      Utils.timeLog('Playing second time.');
      play(video, 1);
    }

    function onLogEvent(e) {
      Utils.timeLog('Event: ' + e.type);
    }

    function onVisibilityChange(e) {
      Utils.timeLog('Event: ' + e.type + ', hidden: ' + document.hidden);
    }

    function onEnded(e) {
      Utils.timeLog('Event: ' + e.type);
      PlayerUtils.removeSession(player).then(function() {
        Utils.setResultInTitle('ENDED');
      }).catch(function(error) {
        Utils.timeLog(error);
        Utils.failTest('Failed PlayerUtils.removeSession');
      });
    }

    function play(video, playCount) {
      Utils.timeLog('eme_player.html::play(): Starting play, hidden=' + document.hidden + ', playCount=' + playCount);
      video.addEventListener('canplay', onLogEvent);
      video.addEventListener('load', onLogEvent);
      video.addEventListener('playing', onLogEvent);
      video.addEventListener('play', onLogEvent);
      video.addEventListener('canplaythrough', onLogEvent);
      video.addEventListener('stalled', onLogEvent);
      video.addEventListener('waiting', onLogEvent);
      video.addEventListener('waitingforkey', onLogEvent);
      document.addEventListener('visibilitychange', onVisibilityChange);
      Utils.resetTitleChange();

      // If multiple media files exist
      if (testConfig.videoFormat && testConfig.audioFormat) {
        var media_types = [];
        var media_files = [];

        media_types = media_types.concat(testConfig.videoFormat);
        media_files = media_files.concat(testConfig.videoFile);
        media_types = media_types.concat(testConfig.audioFormat);
        media_files = media_files.concat(testConfig.audioFile);

        var mediaSource = MediaSourceUtils.loadMediaSource(media_files, media_types);
        video.src = window.URL.createObjectURL(mediaSource);
      }

      if (playCount == 2) {
        // Wait for the first play to complete.
        video.addEventListener('ended', onFirstPlayEnded);
        return video.play();
      }
      // Ended should not fire before onTimeUpdate.
      video.addEventListener('ended', Utils.failTest);
      video.addEventListener('timeupdate', onTimeUpdate);
      if (playCount > 0) {
        return video.play();
      }
    }

    function toggleDisplay(id) {
      var element = document.getElementById(id);
      if (!element)
        return;
      if (element.style['display'] != 'none')
        element.style['display'] = 'none';
      else
        element.style['display'] = '';
    }

    function start() {
      initApp();
      // TODO(jrummell): Support setMediaKeys() after play().
      // See http://crbug.com/675011
      emeApp.createPlayer()
          .then(function(p) {
              player = p;
              return play(player.video, testConfig.playCount);
          }).catch(function(error) {
              Utils.timeLog(error);
              Utils.failTest('Unable to play video.');
          });
    }
  </script>
</html>