| <!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> |