1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// The PlayerUtils provides utility functions to binding common media events 6// to specific player functions. It also provides functions to load media source 7// base on test configurations. 8var PlayerUtils = new function() { 9} 10 11// Prepares a video element for playback by setting default event handlers 12// and source attribute. 13PlayerUtils.registerDefaultEventListeners = function(player) { 14 Utils.timeLog('Registering video event handlers.'); 15 // Map from event name to event listener function name. It is common for 16 // event listeners to be named onEventName. 17 var eventListenerMap = { 18 'needkey': 'onNeedKey', 19 'webkitneedkey': 'onWebkitNeedKey', 20 'webkitkeymessage': 'onWebkitKeyMessage', 21 'webkitkeyadded': 'onWebkitKeyAdded', 22 'webkitkeyerror': 'onWebkitKeyError' 23 }; 24 for (eventName in eventListenerMap) { 25 var eventListenerFunction = player[eventListenerMap[eventName]]; 26 if (eventListenerFunction) { 27 player.video.addEventListener(eventName, function(e) { 28 player[eventListenerMap[e.type]](e); 29 }); 30 } 31 } 32 // List of events that fail tests. 33 var failingEvents = ['error', 'abort']; 34 for (var i = 0; i < failingEvents.length; i++) { 35 player.video.addEventListener(failingEvents[i], Utils.failTest); 36 } 37}; 38 39PlayerUtils.registerEMEEventListeners = function(player) { 40 player.video.addEventListener('needkey', function(message) { 41 42 function addMediaKeySessionListeners(mediaKeySession) { 43 mediaKeySession.addEventListener('message', function(message) { 44 player.video.receivedKeyMessage = true; 45 if (Utils.isHeartBeatMessage(message.message)) { 46 Utils.timeLog('MediaKeySession onMessage - heart beat', message); 47 player.video.receivedHeartbeat = true; 48 } 49 player.onMessage(message); 50 }); 51 mediaKeySession.addEventListener('error', function(error) { 52 Utils.failTest(error, KEY_ERROR); 53 }); 54 } 55 56 Utils.timeLog('Creating new media key session for contentType: ' + 57 message.contentType + ', initData: ' + 58 Utils.getHexString(message.initData)); 59 try { 60 if (message.target.mediaKeys.createSession.length == 0) { 61 // FIXME(jrummell): Remove this test (and else branch) once blink 62 // uses the new API. 63 var session = message.target.mediaKeys.createSession(); 64 addMediaKeySessionListeners(session); 65 session.generateRequest(message.contentType, message.initData) 66 .catch(function(error) { 67 Utils.failTest(error, KEY_ERROR); 68 }); 69 } else { 70 var session = message.target.mediaKeys.createSession( 71 message.contentType, message.initData); 72 session.then(addMediaKeySessionListeners) 73 .catch(function(error) { 74 Utils.failTest(error, KEY_ERROR); 75 }); 76 } 77 } catch (e) { 78 Utils.failTest(e); 79 } 80 }); 81 this.registerDefaultEventListeners(player); 82 try { 83 Utils.timeLog('Setting video media keys: ' + player.testConfig.keySystem); 84 MediaKeys.create(player.testConfig.keySystem).then(function(mediaKeys) { 85 player.video.setMediaKeys(mediaKeys); 86 }).catch(function(error) { 87 Utils.failTest(error, NOTSUPPORTEDERROR); 88 }); 89 } catch (e) { 90 Utils.failTest(e); 91 } 92}; 93 94PlayerUtils.registerPrefixedEMEEventListeners = function(player) { 95 player.video.addEventListener('webkitneedkey', function(message) { 96 var initData = message.initData; 97 if (player.testConfig.sessionToLoad) { 98 Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad); 99 initData = Utils.convertToUint8Array( 100 PREFIXED_API_LOAD_SESSION_HEADER + player.testConfig.sessionToLoad); 101 } 102 Utils.timeLog(player.testConfig.keySystem + 103 ' Generate key request, initData: ' + 104 Utils.getHexString(initData)); 105 try { 106 message.target.webkitGenerateKeyRequest(player.testConfig.keySystem, 107 initData); 108 } catch (e) { 109 Utils.failTest(e); 110 } 111 }); 112 113 player.video.addEventListener('webkitkeyadded', function(message) { 114 Utils.timeLog('onWebkitKeyAdded', message); 115 message.target.receivedKeyAdded = true; 116 }); 117 118 player.video.addEventListener('webkitkeyerror', function(error) { 119 Utils.timeLog('onWebkitKeyError', error); 120 Utils.failTest(error, KEY_ERROR); 121 }); 122 123 player.video.addEventListener('webkitkeymessage', function(message) { 124 Utils.timeLog('onWebkitKeyMessage', message); 125 message.target.receivedKeyMessage = true; 126 if (Utils.isHeartBeatMessage(message.message)) { 127 Utils.timeLog('onWebkitKeyMessage - heart beat', message); 128 message.target.receivedHeartbeat = true; 129 } 130 }); 131 this.registerDefaultEventListeners(player); 132}; 133 134PlayerUtils.setVideoSource = function(player) { 135 if (player.testConfig.useMSE) { 136 Utils.timeLog('Loading media using MSE.'); 137 var mediaSource = 138 MediaSourceUtils.loadMediaSourceFromTestConfig(player.testConfig); 139 player.video.src = window.URL.createObjectURL(mediaSource); 140 } else { 141 Utils.timeLog('Loading media using src.'); 142 player.video.src = player.testConfig.mediaFile; 143 } 144}; 145 146PlayerUtils.initEMEPlayer = function(player) { 147 this.registerEMEEventListeners(player); 148 this.setVideoSource(player); 149}; 150 151PlayerUtils.initPrefixedEMEPlayer = function(player) { 152 this.registerPrefixedEMEEventListeners(player); 153 this.setVideoSource(player); 154}; 155 156// Return the appropriate player based on test configuration. 157PlayerUtils.createPlayer = function(video, testConfig) { 158 // Update keySystem if using prefixed Clear Key since it is not available as a 159 // separate key system to choose from; however it can be set in URL query. 160 var usePrefixedEME = testConfig.usePrefixedEME; 161 if (testConfig.keySystem == CLEARKEY && usePrefixedEME) 162 testConfig.keySystem = PREFIXED_CLEARKEY; 163 164 function getPlayerType(keySystem) { 165 switch (keySystem) { 166 case WIDEVINE_KEYSYSTEM: 167 if (usePrefixedEME) 168 return PrefixedWidevinePlayer; 169 return WidevinePlayer; 170 case PREFIXED_CLEARKEY: 171 return PrefixedClearKeyPlayer; 172 case EXTERNAL_CLEARKEY: 173 case CLEARKEY: 174 if (usePrefixedEME) 175 return PrefixedClearKeyPlayer; 176 return ClearKeyPlayer; 177 case FILE_IO_TEST_KEYSYSTEM: 178 if (usePrefixedEME) 179 return FileIOTestPlayer; 180 default: 181 Utils.timeLog(keySystem + ' is not a known key system'); 182 if (usePrefixedEME) 183 return PrefixedClearKeyPlayer; 184 return ClearKeyPlayer; 185 } 186 } 187 var Player = getPlayerType(testConfig.keySystem); 188 return new Player(video, testConfig); 189}; 190