<!DOCTYPE html>
<html>
<head>
<title>Clear Key Playback with Multiple Sessions</title>
<script src="encrypted-media-utils.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<video></video>
<script>
async_test(function(test)
{
var video = document.querySelector('video');
var content = '../content/test-encrypted-different-av-keys.webm';
var audioMediaKeySession = null;
var videoMediaKeySession = null;
var audioInitDataType = null;
var videoInitDataType = null;
var audioInitData = null;
var videoInitData = null;
var audioKeyProvided = false;
var videoKeyProvided = false;
// The 2 streams use different key ids and different keys.
var audioKeyId = '1234567890123456';
var audioKey = new Uint8Array([0x30, 0x30, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
var videoKeyId = '0123456789012345';
var videoKey = new Uint8Array([0x7A, 0x7A, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
function onEncrypted(event)
{
var keyId = String.fromCharCode.apply(null, new Uint8Array(event.initData));
// To avoid issues when comparing the expected.txt file
// (which logs the events in the order they occur), save
// the initData and make the calls to generateRequest()
// only after both "onencrypted" events are received.
// This prevents a "message" event from occurring before
// both "onencrypted" events are received.
var mediaKeySession = video.mediaKeys.createSession();
if (keyId == videoKeyId) {
assert_equals(videoMediaKeySession, null);
videoMediaKeySession = mediaKeySession;
videoInitDataType = event.initDataType;
videoInitData = event.initData;
// Return if audio "onencrypted" event not yet received.
if (audioMediaKeySession == null)
return;
} else {
assert_equals(keyId, audioKeyId);
assert_equals(audioMediaKeySession, null);
audioMediaKeySession = mediaKeySession;
audioInitDataType = event.initDataType;
audioInitData = event.initData;
// Return if video "onencrypted" event not yet received.
if (videoMediaKeySession == null)
return;
}
// Both sessions have been created.
assert_not_equals(videoMediaKeySession, null);
assert_not_equals(audioMediaKeySession, null);
var promises = [];
waitForEventAndRunStep('message', videoMediaKeySession, onMessage, test);
promises.push(videoMediaKeySession.generateRequest(videoInitDataType, videoInitData));
waitForEventAndRunStep('message', audioMediaKeySession, onMessage, test);
promises.push(audioMediaKeySession.generateRequest(audioInitDataType, audioInitData));
Promise.all(promises).catch(function(error) {
forceTestFailureFromPromise(test, error);
});
}
function onMessage(event)
{
assert_equals(event.messageType, 'license-request');
var keyId = extractSingleKeyIdFromMessage(event.message);
if (event.target == videoMediaKeySession) {
assert_equals(String.fromCharCode.apply(null, keyId), videoKeyId);
var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, videoKey)));
videoMediaKeySession.update(jwkSet).then(function(result) {
videoKeyProvided = true;
}).catch(function(error) {
forceTestFailureFromPromise(test, error);
});
} else {
assert_equals(event.target, audioMediaKeySession);
assert_equals(String.fromCharCode.apply(null, keyId), audioKeyId);
var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, audioKey)));
audioMediaKeySession.update(jwkSet).then(function(result) {
audioKeyProvided = true;
}).catch(function(error) {
forceTestFailureFromPromise(test, error);
});
}
}
function onPlaying(event)
{
// Video should not start playing until both keys have been
// provided.
assert_true(videoKeyProvided);
assert_true(audioKeyProvided);
// Not using waitForEventAndRunStep() to avoid too many
// EVENT(onTimeUpdate) logs.
video.addEventListener('timeupdate', onTimeUpdate, true);
}
function onTimeUpdate(event)
{
if (event.target.currentTime < 0.2)
return;
test.done();
}
navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
return access.createMediaKeys();
}).then(function(mediaKeys) {
waitForEventAndRunStep('encrypted', video, onEncrypted, test);
waitForEventAndRunStep('playing', video, onPlaying, test);
video.src = content;
return video.setMediaKeys(mediaKeys);
}).then(function(result) {
video.play();
}).catch(function(error) {
forceTestFailureFromPromise(test, error);
});
}, 'Playback using Clear Key key system with multiple sessions.');
</script>
</body>
</html>