Skip to content

Commit

Permalink
Fix key status problems with EME polyfills.
Browse files Browse the repository at this point in the history
Our EME polyfills give a key status with a Key ID of '00' (a single 0
byte).  This breaks the Player logic for restricted tracks since it
assumes that those are not playable.  When we get this Key ID, we should
treat the key status as a global status, not for that specific Key ID.

Closes #884
Closes #890

Change-Id: I392550227274fb321d2c223eb8d483a0a4733186
  • Loading branch information
TheModMaker committed Jun 21, 2017
1 parent 651b32a commit 4aa2430
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
15 changes: 14 additions & 1 deletion lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,19 @@ shaka.Player.prototype.onKeyStatus_ = function(keyStatusMap) {
var period = this.streamingEngine_.getCurrentPeriod();
var tracksChanged = false;

// If EME is using a synthetic key, the only key is '00' (a single 0 byte).
// In this case, it is only used to report global success/failure.
// See note about old platforms in: https://goo.gl/KtQMja
var isGlobalStatus = Object.keys(keyStatusMap).length == 1 &&
Object.keys(keyStatusMap)[0] == '00';

if (isGlobalStatus) {
shaka.log.warning(
'Got a synthetic key status event, so we don\'t know the real key ' +
'statuses. If we don\'t have all the keys, you\'ll need to set ' +
'restrictions so we don\'t select those tracks.');
}

period.variants.forEach(function(variant) {
var streams = [];
if (variant.audio) streams.push(variant.audio);
Expand All @@ -2596,7 +2609,7 @@ shaka.Player.prototype.onKeyStatus_ = function(keyStatusMap) {
// Only update if we have a key ID for the stream. If the key isn't
// present, then we don't have that key and it should be restricted.
if (stream.keyId) {
var keyStatus = keyStatusMap[stream.keyId];
var keyStatus = keyStatusMap[isGlobalStatus ? '00' : stream.keyId];
variant.allowedByKeySystem =
!!keyStatus && restrictedStatuses.indexOf(keyStatus) < 0;
}
Expand Down
3 changes: 1 addition & 2 deletions test/media/drm_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ describe('DrmEngine', function() {
}
}).then(function() {
// Some platforms (notably 2017 Tizen TVs) do not fire key status
// events. This is a temporary workaround for the test failure
// in https://github.com/google/shaka-player/issues/891
// events.
var keyStatusTimeout = shaka.test.Util.delay(5);
return Promise.race([keyStatusTimeout, keyStatusEventSeen]);
}).then(function() {
Expand Down
60 changes: 60 additions & 0 deletions test/player_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,66 @@ describe('Player', function() {
}).catch(fail).then(done);
});

it('doesn\'t remove when using synthetic key status', function(done) {
manifest = new shaka.test.ManifestGenerator()
.addPeriod(0)
.addVariant(0)
.addVideo(1).keyId('abc')
.addVariant(2)
.addVideo(3)
.build();

parser = new shaka.test.FakeManifestParser(manifest);
parserFactory = function() { return parser; };
player.load('', 0, parserFactory).then(function() {
// "initialize" the current period.
chooseStreams();
canSwitch();
}).then(function() {
expect(player.getVariantTracks().length).toBe(2);

// A synthetic key status contains a single key status with key '00'.
onKeyStatus({'00': 'usable'});

expect(player.getVariantTracks().length).toBe(2);
}).catch(fail).then(done);
});

it('removes all encrypted tracks for errors with synthetic key status',
function(done) {
manifest = new shaka.test.ManifestGenerator()
.addPeriod(0)
.addVariant(0)
.addVideo(1).keyId('abc')
.addVariant(2)
.addVideo(3).keyId('xyz')
.addVariant(4)
.addVideo(5)
.build();

parser = new shaka.test.FakeManifestParser(manifest);
parserFactory = function() { return parser; };
player.load('', 0, parserFactory)
.then(function() {
// "initialize" the current period.
chooseStreams();
canSwitch();
})
.then(function() {
expect(player.getVariantTracks().length).toBe(3);

// A synthetic key status contains a single key status with key
// '00'.
onKeyStatus({'00': 'internal-error'});

var tracks = player.getVariantTracks();
expect(tracks.length).toBe(1);
expect(tracks[0].id).toBe(4);
})
.catch(fail)
.then(done);
});

it('removes if key system does not support codec', function(done) {
manifest = new shaka.test.ManifestGenerator()
.addPeriod(0)
Expand Down

0 comments on commit 4aa2430

Please sign in to comment.