mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-25 17:45:03 +03:00
428e79a546
This fixes DrmEngine integration tests on IE 11 by: - fixing key status for persistent policies in the IE 11 polyfill - fixing test flow for persistent policies Key status is still broken on Edge 13 Change-Id: If1a1abf53f24cdb31260569603bb5b2886fade43
277 lines
9.3 KiB
JavaScript
277 lines
9.3 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
describe('DrmEngine', function() {
|
|
var support = {};
|
|
|
|
var video;
|
|
var mediaSource;
|
|
var manifest;
|
|
var config;
|
|
|
|
var onErrorSpy;
|
|
var onKeyStatusSpy;
|
|
var drmEngine;
|
|
var mediaSourceEngine;
|
|
var networkingEngine;
|
|
var eventManager;
|
|
|
|
var videoInitSegment;
|
|
var audioInitSegment;
|
|
var videoSegment;
|
|
var audioSegment;
|
|
|
|
// These come from Axinom and use the Axinom license server.
|
|
// TODO: Do not rely on third-party services long-term.
|
|
var videoInitSegmentUri = 'test/assets/multidrm-video-init.mp4';
|
|
var videoSegmentUri = 'test/assets/multidrm-video-segment.mp4';
|
|
var audioInitSegmentUri = 'test/assets/multidrm-audio-init.mp4';
|
|
var audioSegmentUri = 'test/assets/multidrm-audio-segment.mp4';
|
|
|
|
var originalTimeout;
|
|
|
|
beforeAll(function(done) {
|
|
var supportTest = shaka.media.DrmEngine.support().then(function(result) {
|
|
support = result;
|
|
}).catch(fail);
|
|
|
|
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // ms
|
|
|
|
video = /** @type {HTMLVideoElement} */ (document.createElement('video'));
|
|
video.width = '600';
|
|
video.height = '400';
|
|
video.muted = true;
|
|
document.body.appendChild(video);
|
|
|
|
var dummyRequest = {
|
|
allowCrossSiteCredentials: false,
|
|
body: null,
|
|
method: 'GET',
|
|
headers: {},
|
|
retryParameters: shaka.net.NetworkingEngine.defaultRetryParameters(),
|
|
uris: [] // specific URI passed to the plugin is used, not this
|
|
};
|
|
Promise.all([
|
|
supportTest,
|
|
shaka.net.HttpPlugin(videoInitSegmentUri, dummyRequest),
|
|
shaka.net.HttpPlugin(videoSegmentUri, dummyRequest),
|
|
shaka.net.HttpPlugin(audioInitSegmentUri, dummyRequest),
|
|
shaka.net.HttpPlugin(audioSegmentUri, dummyRequest)
|
|
]).then(function(responses) {
|
|
videoInitSegment = responses[1].data;
|
|
videoSegment = responses[2].data;
|
|
audioInitSegment = responses[3].data;
|
|
audioSegment = responses[4].data;
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
beforeEach(function(done) {
|
|
onErrorSpy = jasmine.createSpy('onError');
|
|
onKeyStatusSpy = jasmine.createSpy('onKeyStatus');
|
|
|
|
mediaSource = new MediaSource();
|
|
video.src = window.URL.createObjectURL(mediaSource);
|
|
|
|
networkingEngine = new shaka.net.NetworkingEngine();
|
|
networkingEngine.registerRequestFilter(function(type, request) {
|
|
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) return;
|
|
|
|
request.headers['X-AxDRM-Message'] = [
|
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lk',
|
|
'IjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc2FnZSI6e',
|
|
'yJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiNmU1YTFkMj',
|
|
'YtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflOPv9qHnu3ZWJNZ12j',
|
|
'gkqTabmwXbDWk_47tLNE'
|
|
].join('');
|
|
});
|
|
|
|
drmEngine = new shaka.media.DrmEngine(
|
|
networkingEngine, onErrorSpy, onKeyStatusSpy);
|
|
config = {
|
|
retryParameters: shaka.net.NetworkingEngine.defaultRetryParameters(),
|
|
clearKeys: {},
|
|
advanced: {},
|
|
servers: {
|
|
'com.widevine.alpha':
|
|
'http://drm-widevine-licensing.axtest.net/AcquireLicense',
|
|
'com.microsoft.playready':
|
|
'http://drm-playready-licensing.axtest.net/AcquireLicense'
|
|
}
|
|
};
|
|
drmEngine.configure(config);
|
|
|
|
var drmInfos = [{
|
|
keySystem: 'com.widevine.alpha',
|
|
distinctiveIdentifierRequired: false,
|
|
persistentStateRequired: false
|
|
},{
|
|
keySystem: 'com.microsoft.playready',
|
|
distinctiveIdentifierRequired: false,
|
|
persistentStateRequired: false
|
|
}];
|
|
|
|
manifest = {
|
|
periods: [{
|
|
streamSets: [{
|
|
type: 'video',
|
|
drmInfos: drmInfos,
|
|
streams: [{mimeType: 'video/mp4', codecs: 'avc1.640015'}]
|
|
},{
|
|
type: 'audio',
|
|
drmInfos: drmInfos,
|
|
streams: [{mimeType: 'audio/mp4', codecs: 'mp4a.40.2'}]
|
|
}]
|
|
}]
|
|
};
|
|
|
|
eventManager = new shaka.util.EventManager();
|
|
|
|
eventManager.listen(mediaSource, 'sourceopen', function() {
|
|
eventManager.unlisten(mediaSource, 'sourceopen');
|
|
mediaSourceEngine = new shaka.media.MediaSourceEngine(
|
|
video, mediaSource, null);
|
|
mediaSourceEngine.init({
|
|
'video': 'video/mp4; codecs="avc1.640015"',
|
|
'audio': 'audio/mp4; codecs="mp4a.40.2"'
|
|
});
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function(done) {
|
|
video.removeAttribute('src');
|
|
video.load();
|
|
Promise.all([
|
|
eventManager.destroy(),
|
|
mediaSourceEngine.destroy(),
|
|
networkingEngine.destroy(),
|
|
drmEngine.destroy()
|
|
]).then(done);
|
|
});
|
|
|
|
afterAll(function() {
|
|
document.body.removeChild(video);
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
|
|
});
|
|
|
|
function checkKeySystems() {
|
|
// Our test asset for this suite can use any of these key systems:
|
|
if (!support['com.widevine.alpha'] &&
|
|
!support['com.microsoft.playready']) {
|
|
// pending() throws a special exception that Jasmine uses to skip a test.
|
|
// It can only be used from inside it(), not describe() or beforeEach().
|
|
pending('Skipping DrmEngine tests.');
|
|
// The rest of the test will not run.
|
|
}
|
|
}
|
|
|
|
describe('basic flow', function() {
|
|
it('gets a license and can play encrypted segments', function(done) {
|
|
checkKeySystems();
|
|
|
|
// The error callback should not be invoked.
|
|
onErrorSpy.and.callFake(fail);
|
|
|
|
var originalRequest = networkingEngine.request;
|
|
var requestComplete;
|
|
var requestSpy = jasmine.createSpy('request');
|
|
var requestMade = new shaka.util.PublicPromise();
|
|
requestSpy.and.callFake(function() {
|
|
requestMade.resolve();
|
|
requestComplete = originalRequest.apply(this, arguments);
|
|
return requestComplete;
|
|
});
|
|
networkingEngine.request = requestSpy;
|
|
|
|
var encryptedEventSeen = new shaka.util.PublicPromise();
|
|
eventManager.listen(video, 'encrypted', function() {
|
|
encryptedEventSeen.resolve();
|
|
});
|
|
eventManager.listen(video, 'error', function() {
|
|
fail('MediaError code ' + video.error.code);
|
|
var extended = video.error.msExtendedCode;
|
|
if (extended) {
|
|
if (extended < 0) {
|
|
extended += Math.pow(2, 32);
|
|
}
|
|
fail('MediaError msExtendedCode ' + extended.toString(16));
|
|
}
|
|
});
|
|
|
|
var keyStatusEventSeen = new shaka.util.PublicPromise();
|
|
onKeyStatusSpy.and.callFake(function() {
|
|
keyStatusEventSeen.resolve();
|
|
});
|
|
|
|
drmEngine.init(manifest, /* offline */ false).then(function() {
|
|
return drmEngine.attach(video);
|
|
}).then(function() {
|
|
return mediaSourceEngine.appendBuffer('video', videoInitSegment,
|
|
null, null);
|
|
}).then(function() {
|
|
return mediaSourceEngine.appendBuffer('audio', audioInitSegment,
|
|
null, null);
|
|
}).then(function() {
|
|
return encryptedEventSeen;
|
|
}).then(function() {
|
|
// With PlayReady, a persistent license policy can cause a different
|
|
// chain of events. In particular, the request is bypassed and we get
|
|
// a usable key right away.
|
|
return Promise.race([requestMade, keyStatusEventSeen]);
|
|
}).then(function() {
|
|
if (requestSpy.calls.count()) {
|
|
// We made a license request.
|
|
// Only one request should have been made.
|
|
expect(requestSpy.calls.count()).toBe(1);
|
|
// So it's reasonable to assume that this requestComplete Promise is
|
|
// waiting on the correct request.
|
|
return requestComplete;
|
|
} else {
|
|
// This was probably a PlayReady persistent license.
|
|
}
|
|
}).then(function() {
|
|
return keyStatusEventSeen;
|
|
}).then(function() {
|
|
var call = onKeyStatusSpy.calls.mostRecent();
|
|
if (call) {
|
|
var map = call.args[0];
|
|
expect(Object.keys(map).length).not.toBe(0);
|
|
for (var k in map) {
|
|
expect(map[k]).toBe('usable');
|
|
}
|
|
}
|
|
|
|
return mediaSourceEngine.appendBuffer('video', videoSegment,
|
|
null, null);
|
|
}).then(function() {
|
|
return mediaSourceEngine.appendBuffer('audio', audioSegment,
|
|
null, null);
|
|
}).then(function() {
|
|
expect(video.buffered.end(0)).toBeGreaterThan(0);
|
|
video.play();
|
|
// Try to play for 5 seconds.
|
|
return shaka.test.Util.delay(5);
|
|
}).then(function() {
|
|
// Something should have played by now.
|
|
expect(video.readyState).toBeGreaterThan(1);
|
|
expect(video.currentTime).toBeGreaterThan(0);
|
|
}).catch(fail).then(done);
|
|
});
|
|
});
|
|
});
|