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