blob: 5dbe0027094b2e3a153981dfe8a1d359b513ba3f [file] [log] [blame]
// 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);
};