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.
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.
8 var PlayerUtils = new function() {
11 // Prepares a video element for playback by setting default event handlers
12 // and source attribute.
13 PlayerUtils.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 'encrypted': 'onEncrypted',
19 'webkitneedkey': 'onWebkitNeedKey',
20 'webkitkeymessage': 'onWebkitKeyMessage',
21 'webkitkeyadded': 'onWebkitKeyAdded',
22 'webkitkeyerror': 'onWebkitKeyError'
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);
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);
39 PlayerUtils.registerEMEEventListeners = function(player) {
40 player.video.addEventListener('encrypted', function(message) {
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;
49 player.onMessage(message);
51 mediaKeySession.addEventListener('error', function(error) {
52 Utils.failTest(error, KEY_ERROR);
57 if (player.testConfig.sessionToLoad) {
58 Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
59 var session = message.target.mediaKeys.createSession('persistent');
60 addMediaKeySessionListeners(session);
61 session.load(player.testConfig.sessionToLoad)
62 .catch(function(error) { Utils.failTest(error, KEY_ERROR); });
64 Utils.timeLog('Creating new media key session for initDataType: ' +
65 message.initDataType + ', initData: ' +
66 Utils.getHexString(new Uint8Array(message.initData)));
67 var session = message.target.mediaKeys.createSession();
68 addMediaKeySessionListeners(session);
69 session.generateRequest(message.initDataType, message.initData)
70 .catch(function(error) {
71 Utils.failTest(error, KEY_ERROR);
79 this.registerDefaultEventListeners(player);
81 Utils.timeLog('Setting video media keys: ' + player.testConfig.keySystem);
82 if (typeof navigator.requestMediaKeySystemAccess == 'function') {
83 navigator.requestMediaKeySystemAccess(player.testConfig.keySystem)
84 .then(function(access) { return access.createMediaKeys(); })
85 .then(function(mediaKeys) { player.video.setMediaKeys(mediaKeys); })
86 .catch(function(error) { Utils.failTest(error, NOTSUPPORTEDERROR); });
88 // TODO(jrummell): Remove this once the blink change for
89 // requestMediaKeySystemAccess lands.
90 MediaKeys.create(player.testConfig.keySystem)
91 .then(function(mediaKeys) { player.video.setMediaKeys(mediaKeys); })
92 .catch(function(error) { Utils.failTest(error, NOTSUPPORTEDERROR); });
99 PlayerUtils.registerPrefixedEMEEventListeners = function(player) {
100 player.video.addEventListener('webkitneedkey', function(message) {
101 var initData = message.initData;
102 if (player.testConfig.sessionToLoad) {
103 Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
104 initData = Utils.convertToUint8Array(
105 PREFIXED_API_LOAD_SESSION_HEADER + player.testConfig.sessionToLoad);
107 Utils.timeLog(player.testConfig.keySystem +
108 ' Generate key request, initData: ' +
109 Utils.getHexString(initData));
111 message.target.webkitGenerateKeyRequest(player.testConfig.keySystem,
118 player.video.addEventListener('webkitkeyadded', function(message) {
119 Utils.timeLog('onWebkitKeyAdded', message);
120 message.target.receivedKeyAdded = true;
123 player.video.addEventListener('webkitkeyerror', function(error) {
124 Utils.timeLog('onWebkitKeyError', error);
125 Utils.failTest(error, KEY_ERROR);
128 player.video.addEventListener('webkitkeymessage', function(message) {
129 Utils.timeLog('onWebkitKeyMessage', message);
130 message.target.receivedKeyMessage = true;
131 if (Utils.isHeartBeatMessage(message.message)) {
132 Utils.timeLog('onWebkitKeyMessage - heart beat', message);
133 message.target.receivedHeartbeat = true;
136 this.registerDefaultEventListeners(player);
139 PlayerUtils.setVideoSource = function(player) {
140 if (player.testConfig.useMSE) {
141 Utils.timeLog('Loading media using MSE.');
143 MediaSourceUtils.loadMediaSourceFromTestConfig(player.testConfig);
144 player.video.src = window.URL.createObjectURL(mediaSource);
146 Utils.timeLog('Loading media using src.');
147 player.video.src = player.testConfig.mediaFile;
151 PlayerUtils.initEMEPlayer = function(player) {
152 this.registerEMEEventListeners(player);
153 this.setVideoSource(player);
156 PlayerUtils.initPrefixedEMEPlayer = function(player) {
157 this.registerPrefixedEMEEventListeners(player);
158 this.setVideoSource(player);
161 // Return the appropriate player based on test configuration.
162 PlayerUtils.createPlayer = function(video, testConfig) {
163 // Update keySystem if using prefixed Clear Key since it is not available as a
164 // separate key system to choose from; however it can be set in URL query.
165 var usePrefixedEME = testConfig.usePrefixedEME;
166 if (testConfig.keySystem == CLEARKEY && usePrefixedEME)
167 testConfig.keySystem = PREFIXED_CLEARKEY;
169 function getPlayerType(keySystem) {
171 case WIDEVINE_KEYSYSTEM:
173 return PrefixedWidevinePlayer;
174 return WidevinePlayer;
175 case PREFIXED_CLEARKEY:
176 return PrefixedClearKeyPlayer;
177 case EXTERNAL_CLEARKEY:
180 return PrefixedClearKeyPlayer;
181 return ClearKeyPlayer;
182 case FILE_IO_TEST_KEYSYSTEM:
184 return FileIOTestPlayer;
186 Utils.timeLog(keySystem + ' is not a known key system');
188 return PrefixedClearKeyPlayer;
189 return ClearKeyPlayer;
192 var Player = getPlayerType(testConfig.keySystem);
193 return new Player(video, testConfig);