| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Multiple playbacks alternating between encrypted and clear sources.</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 isUpdatePromiseResolved = false; |
| var encryptedEventCount = 0; |
| var playbackCount = 0; |
| |
| // Content to be played. These files must be the same format. |
| var encryptedContent = '../content/test-encrypted.webm'; |
| var unencryptedContent = '../content/test.webm'; |
| |
| var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, |
| 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]); |
| |
| function onEncrypted(event) |
| { |
| assert_equals(event.target, video); |
| assert_true(event instanceof window.MediaEncryptedEvent); |
| assert_equals(event.type, 'encrypted'); |
| |
| // The same decryption key is used by both the audio and |
| // the video streams so only create a session once. To |
| // avoid issues when comparing the expected.txt file |
| // (which logs the events in the order they occur), create |
| // the session on the second event. This also ensures we |
| // see both events. |
| if (++encryptedEventCount != 2) |
| return; |
| |
| assert_false(video.mediaKeys === null, "video.mediaKeys is null."); |
| var mediaKeySession = video.mediaKeys.createSession(); |
| waitForEventAndRunStep('message', mediaKeySession, onMessage, test); |
| mediaKeySession.generateRequest(event.initDataType, event.initData).catch(function(error) { |
| forceTestFailureFromPromise(test, error); |
| }); |
| } |
| |
| function onMessage(event) |
| { |
| assert_true(event instanceof window.MediaKeyMessageEvent); |
| assert_equals(event.type, 'message'); |
| assert_equals(event.messageType, 'license-request'); |
| |
| var keyId = extractSingleKeyIdFromMessage(event.message); |
| var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey))); |
| event.target.update(jwkSet).then(function(result) { |
| isUpdatePromiseResolved = true; |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error); |
| }); |
| } |
| |
| function onPlaying(event) |
| { |
| // Not using waitForEventAndRunStep() to avoid too many |
| // EVENT(onTimeUpdate) logs. |
| video.addEventListener('timeupdate', onTimeUpdate, true); |
| } |
| |
| function onTimeUpdate(event) |
| { |
| if (event.target.currentTime < 0.2 || !isUpdatePromiseResolved) |
| return; |
| |
| video.removeEventListener('timeupdate', onTimeUpdate, true); |
| |
| if (playbackCount > 2) { |
| test.done(); |
| return; |
| } |
| |
| playbackCount++; |
| |
| resetSrc().then(function(){ |
| startPlayback(); |
| }); |
| } |
| |
| function resetSrc() { |
| encryptedEventCount = 0; |
| video.removeAttribute('src'); |
| video.load(); |
| return video.setMediaKeys(null); |
| } |
| |
| function startPlayback() { |
| // Alternate between unencrypted and encrypted files. |
| if (playbackCount % 2) { |
| // Unencrypted files don't require MediaKeys. |
| video.src = unencryptedContent; |
| video.play(); |
| return; |
| } |
| |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(encryptedContent)).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| return video.setMediaKeys(mediaKeys); |
| }).then(function(result) { |
| video.src = encryptedContent; |
| assert_false(video.mediaKeys === null, "video.mediaKeys is null."); |
| video.play(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error); |
| }); |
| } |
| |
| waitForEventAndRunStep('playing', video, onPlaying, test); |
| waitForEventAndRunStep('encrypted', video, onEncrypted, test); |
| startPlayback(); |
| }, 'Multiple playbacks alternating between encrypted and clear sources.'); |
| </script> |
| </body> |
| </html> |