Skip to content

Commit d4bb311

Browse files
tykus160joeyparrish
authored andcommitted
fix(DASH): Fix playback of ClearKey when only part of keys are defined (#8055)
Fixes #8052 Key ids were not used when looking for stream duplicates, so it was possible to filter out streams without accompanying configuration. Now we will use key ids as well for duplicates detection.
1 parent 34e3c0c commit d4bb311

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

lib/util/periods.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ shaka.util.PeriodCombiner = class {
836836
clone.roles = clone.roles.slice();
837837
clone.segmentIndex = null;
838838
clone.emsgSchemeIdUris = [];
839-
clone.keyIds = new Set();
839+
clone.keyIds = new Set(stream.keyIds);
840840
clone.closedCaptions = stream.closedCaptions ?
841841
new Map(stream.closedCaptions) : null;
842842
clone.trickModeVideo = null;
@@ -860,7 +860,7 @@ shaka.util.PeriodCombiner = class {
860860
clone.roles = clone.roles.slice();
861861
// These are wiped out now and rebuilt later from the various per-period
862862
// streams that match this output.
863-
clone.keyIds = new Set();
863+
clone.keyIds = new Set(streamDb.keyIds);
864864
clone.segments = [];
865865
clone.variantIds = [];
866866
clone.closedCaptions = streamDb.closedCaptions ?
@@ -1772,6 +1772,7 @@ shaka.util.PeriodCombiner = class {
17721772
v.roles,
17731773
v.closedCaptions ? Array.from(v.closedCaptions.entries()) : null,
17741774
v.bandwidth,
1775+
Array.from(v.keyIds),
17751776
]);
17761777
}
17771778

@@ -1794,6 +1795,7 @@ shaka.util.PeriodCombiner = class {
17941795
a.roles,
17951796
a.audioSamplingRate,
17961797
a.primary,
1798+
Array.from(a.keyIds),
17971799
]);
17981800
}
17991801

test/util/periods_unit.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,84 @@ describe('PeriodCombiner', () => {
603603
}
604604
});
605605

606+
it('Filters out duplicates based on keyids', async () => {
607+
// v1 and v3 are duplicates
608+
const v1 = makeVideoStream(1280);
609+
v1.frameRate = 30000/1001;
610+
v1.originalId = 'v1';
611+
v1.bandwidth = 6200000;
612+
v1.keyIds = new Set(['deadbeefdeadbeefdeadbeefdeadbeef']);
613+
614+
const v2 = makeVideoStream(1280);
615+
v2.frameRate = 30000/1001;
616+
v2.originalId = 'v2';
617+
v2.bandwidth = 6200000;
618+
v2.keyIds = new Set(['02030507011013017019023029031037']);
619+
620+
const v3 = makeVideoStream(1280);
621+
v3.frameRate = 30000/1001;
622+
v3.originalId = 'v3';
623+
v3.bandwidth = 6200000;
624+
v3.keyIds = new Set(['deadbeefdeadbeefdeadbeefdeadbeef']);
625+
626+
// a1 and a2 are duplicates.
627+
const a1 = makeAudioStream('en', /* channels= */ 2);
628+
a1.originalId = 'a1';
629+
a1.bandwidth = 65106;
630+
a1.roles = ['role1', 'role2'];
631+
a1.codecs = 'mp4a.40.2';
632+
a1.keyIds = new Set(['deadbeefdeadbeefdeadbeefdeadbeef']);
633+
634+
const a2 = makeAudioStream('en', /* channels= */ 2);
635+
a2.originalId = 'a2';
636+
a2.bandwidth = 65106;
637+
a2.roles = ['role1', 'role2'];
638+
a2.codecs = 'mp4a.40.2';
639+
a2.keyIds = new Set(['deadbeefdeadbeefdeadbeefdeadbeef']);
640+
641+
const a3 = makeAudioStream('en', /* channels= */ 2);
642+
a3.originalId = 'a3';
643+
a3.bandwidth = 65106;
644+
a3.roles = ['role1', 'role2'];
645+
a3.codecs = 'mp4a.40.2';
646+
a3.keyIds = new Set(['02030507011013017019023029031037']);
647+
648+
/** @type {!Array<shaka.extern.Period>} */
649+
const periods = [
650+
{
651+
id: '1',
652+
videoStreams: [
653+
v1,
654+
v2,
655+
v3,
656+
],
657+
audioStreams: [
658+
a1,
659+
a2,
660+
a3,
661+
],
662+
textStreams: [],
663+
imageStreams: [],
664+
},
665+
];
666+
667+
await combiner.combinePeriods(periods, /* isDynamic= */ true);
668+
const variants = combiner.getVariants();
669+
expect(variants.length).toBe(4);
670+
671+
// v1 should've been filtered out
672+
const videoIds = variants.map((v) => v.video.originalId);
673+
for (const id of videoIds) {
674+
expect(id).not.toBe('v1');
675+
}
676+
677+
// a1 should've been filtered out
678+
const audioIds = variants.map((v) => v.audio.originalId);
679+
for (const id of audioIds) {
680+
expect(id).not.toBe('a1');
681+
}
682+
});
683+
606684
// Regression test for #6054, where we failed on multi-period content with
607685
// different numbers of forced-subtitle streams per period.
608686
it('Does not combine subtitle and forced-subtitle tracks', async () => {

0 commit comments

Comments
 (0)