4 <title>Clear Key Playback with Multiple Sessions</title>
5 <script src="encrypted-media-utils.js"></script>
6 <script src="../../resources/testharness.js"></script>
7 <script src="../../resources/testharnessreport.js"></script>
10 <video id="testVideo"></video>
12 <p>Test playback of encrypted media using Clear Key key system with multiple sessions.</p>
14 async_test(function(test)
16 var video = document.getElementById('testVideo');
17 var audioMediaKeySession = null;
18 var videoMediaKeySession = null;
19 var audioInitDataType = null;
20 var videoInitDataType = null;
21 var audioInitData = null;
22 var videoInitData = null;
23 var audioKeyProvided = false;
24 var videoKeyProvided = false;
26 // The 2 streams use different key ids and different keys.
27 var audioKeyId = '1234567890123456';
28 var audioKey = new Uint8Array([0x30, 0x30, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
29 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
30 var videoKeyId = '0123456789012345';
31 var videoKey = new Uint8Array([0x7A, 0x7A, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B,
32 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A]);
34 function onEncrypted(event)
36 var keyId = String.fromCharCode.apply(null, new Uint8Array(event.initData));
38 // To avoid issues when comparing the expected.txt file
39 // (which logs the events in the order they occur), save
40 // the initData and make the calls to generateRequest()
41 // only after both "onencrypted" events are received.
42 // This prevents a "message" event from occurring before
43 // both "onencrypted" events are received.
44 var mediaKeySession = video.mediaKeys.createSession();
45 if (keyId == videoKeyId) {
46 assert_equals(videoMediaKeySession, null);
47 videoMediaKeySession = mediaKeySession;
48 videoInitDataType = event.initDataType;
49 videoInitData = event.initData;
50 // Return if audio "onencrypted" event not yet received.
51 if (audioMediaKeySession == null)
54 assert_equals(keyId, audioKeyId);
55 assert_equals(audioMediaKeySession, null);
56 audioMediaKeySession = mediaKeySession;
57 audioInitDataType = event.initDataType;
58 audioInitData = event.initData;
59 // Return if video "onencrypted" event not yet received.
60 if (videoMediaKeySession == null)
64 // Both sessions have been created.
65 assert_not_equals(videoMediaKeySession, null);
66 assert_not_equals(audioMediaKeySession, null);
69 waitForEventAndRunStep('message', videoMediaKeySession, onMessage, test);
70 promises.push(videoMediaKeySession.generateRequest(videoInitDataType, videoInitData));
72 waitForEventAndRunStep('message', audioMediaKeySession, onMessage, test);
73 promises.push(audioMediaKeySession.generateRequest(audioInitDataType, audioInitData));
75 Promise.all(promises).catch(function(error) {
76 forceTestFailureFromPromise(test, error);
80 function onMessage(event)
82 var keyId = extractSingleKeyIdFromMessage(event.message);
83 if (event.target == videoMediaKeySession) {
84 assert_equals(String.fromCharCode.apply(null, keyId), videoKeyId);
85 var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, videoKey)));
86 videoMediaKeySession.update(jwkSet).then(function(result) {
87 videoKeyProvided = true;
88 }).catch(function(error) {
89 forceTestFailureFromPromise(test, error);
92 assert_equals(event.target, audioMediaKeySession);
93 assert_equals(String.fromCharCode.apply(null, keyId), audioKeyId);
94 var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, audioKey)));
95 audioMediaKeySession.update(jwkSet).then(function(result) {
96 audioKeyProvided = true;
97 }).catch(function(error) {
98 forceTestFailureFromPromise(test, error);
103 function onPlaying(event)
105 // Video should not start playing until both keys have been
107 assert_true(videoKeyProvided);
108 assert_true(audioKeyProvided);
110 // Not using waitForEventAndRunStep() to avoid too many
111 // EVENT(onTimeUpdate) logs.
112 video.addEventListener('timeupdate', onTimeUpdate, true);
115 function onTimeUpdate(event)
117 if (event.target.currentTime < 0.2)
123 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
124 return access.createMediaKeys();
125 }).then(function(mediaKeys) {
126 waitForEventAndRunStep('encrypted', video, onEncrypted, test);
127 waitForEventAndRunStep('playing', video, onPlaying, test);
128 video.src = '../content/test-encrypted-different-av-keys.webm';
129 return video.setMediaKeys(mediaKeys);
130 }).then(function(result) {
132 }).catch(function(error) {
133 forceTestFailureFromPromise(test, error);
135 }, 'Playback using Clear Key key system with multiple sessions.');