| <!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, false); |
| } |
| |
| 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, 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); |
| video.addEventListener('waitingforkey', onLogEvent); |
| document.addEventListener('visibilitychange', onVisibilityChange); |
| Utils.resetTitleChange(); |
| if (playTwice) { |
| // 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); |
| 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.playTwice); |
| }).catch(function(error) { |
| Utils.timeLog(error); |
| Utils.failTest('Unable to play video.'); |
| }); |
| } |
| </script> |
| </html> |