Skip to content

Commit a7f0be7

Browse files
authored
fix: Fix HLS lazy-loading with DRM (#4646)
Now that DRM info is only parsed after playback has begun, the manifest parser needs to communicate back to the other components that new DRM info is available after lazy-loading a playlist. Closes #4622
1 parent 941ed4e commit a7f0be7

13 files changed

+65
-15
lines changed

externs/shaka/manifest_parser.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ shaka.extern.ManifestParser = class {
112112
* isLowLatencyMode: function():boolean,
113113
* isAutoLowLatencyMode: function():boolean,
114114
* enableLowLatencyMode: function(),
115-
* updateDuration: function()
115+
* updateDuration: function(),
116+
* newDrmInfo: function(shaka.extern.Stream)
116117
* }}
117118
*
118119
* @description
@@ -150,6 +151,9 @@ shaka.extern.ManifestParser = class {
150151
* Enable low latency streaming mode.
151152
* @property {function()} updateDuration
152153
* Update the presentation duration based on PresentationTimeline.
154+
* @property {function(shaka.extern.Stream)} newDrmInfo
155+
* Inform the player of new DRM info that needs to be processed for the given
156+
* stream.
153157
* @exportDoc
154158
*/
155159
shaka.extern.ManifestParser.PlayerInterface;

lib/hls/hls_parser.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,12 @@ shaka.hls.HlsParser = class {
16151615
stream.roles = realStream.roles;
16161616
stream.mimeType = realStream.mimeType;
16171617

1618+
// Since we lazy-loaded this content, the player may need to create new
1619+
// sessions for the DRM info in this stream.
1620+
if (stream.drmInfos.length) {
1621+
this.playerInterface_.newDrmInfo(stream);
1622+
}
1623+
16181624
const ContentType = shaka.util.ManifestParserUtils.ContentType;
16191625
if (type == ContentType.VIDEO || type == ContentType.AUDIO) {
16201626
for (const otherStreamInfo of this.uriToStreamInfosMap_.values()) {

lib/offline/storage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,7 @@ shaka.offline.Storage = class {
11701170
isAutoLowLatencyMode: () => false,
11711171
enableLowLatencyMode: () => {},
11721172
updateDuration: () => {},
1173+
newDrmInfo: (stream) => {},
11731174
};
11741175

11751176
parser.configure(config.manifest);

lib/player.js

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
18891889
this.streamingEngine_.updateDuration();
18901890
}
18911891
},
1892+
newDrmInfo: (stream) => {
1893+
// We may need to create new sessions for any new init data.
1894+
const currentDrmInfo =
1895+
this.drmEngine_ ? this.drmEngine_.getDrmInfo() : null;
1896+
// DrmEngine.newInitData() requires mediaKeys to be available.
1897+
if (currentDrmInfo && this.drmEngine_.getMediaKeys()) {
1898+
this.processDrmInfos_(currentDrmInfo.keySystem, stream);
1899+
}
1900+
},
18921901
};
18931902

18941903
const startTime = Date.now() / 1000;
@@ -5410,27 +5419,39 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
54105419
}
54115420

54125421
// We may need to create new sessions for any new init data.
5413-
const curDrmInfo = this.drmEngine_ ? this.drmEngine_.getDrmInfo() : null;
5422+
const currentDrmInfo =
5423+
this.drmEngine_ ? this.drmEngine_.getDrmInfo() : null;
54145424
// DrmEngine.newInitData() requires mediaKeys to be available.
5415-
if (curDrmInfo && this.drmEngine_.getMediaKeys()) {
5425+
if (currentDrmInfo && this.drmEngine_.getMediaKeys()) {
54165426
for (const variant of manifest.variants) {
5417-
const videoDrmInfos = variant.video ? variant.video.drmInfos : [];
5418-
const audioDrmInfos = variant.audio ? variant.audio.drmInfos : [];
5419-
const drmInfos = videoDrmInfos.concat(audioDrmInfos);
5420-
for (const drmInfo of drmInfos) {
5421-
// Ignore any data for different key systems.
5422-
if (drmInfo.keySystem == curDrmInfo.keySystem) {
5423-
for (const initData of (drmInfo.initData || [])) {
5424-
this.drmEngine_.newInitData(
5425-
initData.initDataType, initData.initData);
5426-
}
5427-
}
5428-
}
5427+
this.processDrmInfos_(currentDrmInfo.keySystem, variant.video);
5428+
this.processDrmInfos_(currentDrmInfo.keySystem, variant.audio);
54295429
}
54305430
}
54315431
this.checkRestrictedVariants_(manifest);
54325432
}
54335433

5434+
/**
5435+
* @param {string} keySystem
5436+
* @param {?shaka.extern.Stream} stream
5437+
* @private
5438+
*/
5439+
processDrmInfos_(keySystem, stream) {
5440+
if (!stream) {
5441+
return;
5442+
}
5443+
5444+
for (const drmInfo of stream.drmInfos) {
5445+
// Ignore any data for different key systems.
5446+
if (drmInfo.keySystem == keySystem) {
5447+
for (const initData of (drmInfo.initData || [])) {
5448+
this.drmEngine_.newInitData(
5449+
initData.initDataType, initData.initData);
5450+
}
5451+
}
5452+
}
5453+
}
5454+
54345455
/**
54355456
* @private
54365457
*/

test/dash/dash_parser_content_protection_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('DashParser ContentProtection', () => {
4444
isAutoLowLatencyMode: () => false,
4545
enableLowLatencyMode: () => {},
4646
updateDuration: () => {},
47+
newDrmInfo: (stream) => {},
4748
};
4849

4950
const actual = await dashParser.start(

test/dash/dash_parser_live_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('DashParser Live', () => {
3737
isAutoLowLatencyMode: () => false,
3838
enableLowLatencyMode: () => {},
3939
updateDuration: () => {},
40+
newDrmInfo: (stream) => {},
4041
};
4142
});
4243

test/dash/dash_parser_manifest_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ describe('DashParser Manifest', () => {
5353
isAutoLowLatencyMode: () => false,
5454
enableLowLatencyMode: () => {},
5555
updateDuration: () => {},
56+
newDrmInfo: (stream) => {},
5657
};
5758
});
5859

test/dash/dash_parser_segment_base_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ describe('DashParser SegmentBase', () => {
3939
isAutoLowLatencyMode: () => false,
4040
enableLowLatencyMode: () => {},
4141
updateDuration: () => {},
42+
newDrmInfo: (stream) => {},
4243
};
4344
});
4445

test/dash/dash_parser_segment_list_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ describe('DashParser SegmentList', () => {
349349
isAutoLowLatencyMode: () => false,
350350
enableLowLatencyMode: () => {},
351351
updateDuration: () => {},
352+
newDrmInfo: (stream) => {},
352353
};
353354
const manifest = await dashParser.start('dummy://foo', playerInterface);
354355
const stream = manifest.variants[0].video;

test/dash/dash_parser_segment_template_unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe('DashParser SegmentTemplate', () => {
4848
isAutoLowLatencyMode: () => false,
4949
enableLowLatencyMode: () => {},
5050
updateDuration: () => {},
51+
newDrmInfo: (stream) => {},
5152
};
5253
});
5354

0 commit comments

Comments
 (0)