<!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 initApp() {
      testConfig = new TestConfig();
      testConfig.loadQueryParams();
      // Update document with test configuration values.
      emeApp = new EMEApp(testConfig);
      setInterval(function () {
                      Utils.timeLog('heartbeat #' + ++heartbeatCount);
                  }, 1000);
    }

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

      // Renewal message may be fired around the start of playback; check for it
      // after a delay to avoid timing issues.
      if (testConfig.keySystem == EXTERNAL_CLEARKEY_RENEWAL &&
          !video.receivedRenewalMessage) {
        Utils.failTest('license-renewal message not received.');
      }

      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, false);
    }

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

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

    function play(video, playTwice) {
      Utils.timeLog('Starting play, hidden: ' + document.hidden);
      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);
      document.addEventListener('visibilitychange', onVisibilityChange);
      Utils.resetTitleChange();
      if (playTwice) {
        // Wait for the first play to complete.
        video.addEventListener('ended', onFirstPlayEnded);
        video.play();
        return;
      }
      // Ended should not fire before onTimeUpdate.
      video.addEventListener('ended', Utils.failTest);
      video.addEventListener('timeupdate', onTimeUpdate);
      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();  
      emeApp.createPlayer()
          .then(function(p) {
              player = p;
              play(player.video, testConfig.playTwice);
          }).catch(function(error) {
              Utils.timeLog(error);
              Utils.failTest('Unable to play video.');
          });
    }
  </script>
</html>
