Skip to content

Commit

Permalink
fix(HLS): Avoid duplicate AES requests (#6399)
Browse files Browse the repository at this point in the history
Fixes #6407
  • Loading branch information
avelad committed Apr 5, 2024
1 parent 0fc5814 commit ea740ba
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
34 changes: 19 additions & 15 deletions lib/hls/hls_parser.js
Expand Up @@ -219,7 +219,10 @@ shaka.hls.HlsParser = class {
/** @private {Map.<string, !shaka.extern.aesKey>} */
this.aesKeyInfoMap_ = new Map();

/** @private {Map.<string, string>} */
/** @private {Map.<string, !Promise.<shaka.extern.Response>>} */
this.aesKeyMap_ = new Map();

/** @private {Map.<string, !Promise.<shaka.extern.Response>>} */
this.identityKeyMap_ = new Map();

/** @private {Map.<!shaka.media.InitSegmentReference, ?string>} */
Expand Down Expand Up @@ -306,6 +309,7 @@ shaka.hls.HlsParser = class {
this.globalVariables_.clear();
this.mapTagToInitSegmentRefMap_.clear();
this.aesKeyInfoMap_.clear();
this.aesKeyMap_.clear();
this.identityKeyMap_.clear();
this.identityKidMap_.clear();

Expand Down Expand Up @@ -2926,11 +2930,15 @@ shaka.hls.HlsParser = class {
const keyUris = shaka.hls.Utils.constructSegmentUris(
getUris(), drmTag.getRequiredAttrValue('URI'), variables);

const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
const request = shaka.net.NetworkingEngine.makeRequest(
keyUris, this.config_.retryParameters);
const keyResponse =
await this.makeNetworkRequest_(request, requestType);
const keyMapKey = keyUris.sort().join('');
if (!this.aesKeyMap_.has(keyMapKey)) {
const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
const request = shaka.net.NetworkingEngine.makeRequest(
keyUris, this.config_.retryParameters);
const keyResponse = this.makeNetworkRequest_(request, requestType);
this.aesKeyMap_.set(keyMapKey, keyResponse);
}
const keyResponse = await this.aesKeyMap_.get(keyMapKey);

// keyResponse.status is undefined when URI is "data:text/plain;base64,"
if (!keyResponse.data ||
Expand Down Expand Up @@ -4264,20 +4272,16 @@ shaka.hls.HlsParser = class {
const keyUris = shaka.hls.Utils.constructSegmentUris(
getUris(), drmTag.getRequiredAttrValue('URI'), variables);

let key;
const keyMapKey = keyUris.sort().join('');
if (this.identityKeyMap_.has(keyMapKey)) {
key = this.identityKeyMap_.get(keyMapKey);
} else {
if (!this.identityKeyMap_.has(keyMapKey)) {
const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
const request = shaka.net.NetworkingEngine.makeRequest(
keyUris, this.config_.retryParameters);
const keyResponse =
await this.makeNetworkRequest_(request, requestType);

key = shaka.util.Uint8ArrayUtils.toHex(keyResponse.data);
this.identityKeyMap_.set(keyMapKey, key);
const keyResponse = this.makeNetworkRequest_(request, requestType);
this.identityKeyMap_.set(keyMapKey, keyResponse);
}
const keyResponse = await this.identityKeyMap_.get(keyMapKey);
const key = shaka.util.Uint8ArrayUtils.toHex(keyResponse.data);

// NOTE: The ClearKey CDM requires a key-id to key mapping. HLS doesn't
// provide a key ID anywhere. So although we could use the 'URI' attribute
Expand Down
10 changes: 10 additions & 0 deletions test/hls/hls_parser_integration.js
Expand Up @@ -70,6 +70,13 @@ describe('HlsParser', () => {
});

it('supports AES-256 streaming', async () => {
let keyRequests = 0;
const netEngine = player.getNetworkingEngine();
netEngine.registerRequestFilter((type, request, context) => {
if (type == shaka.net.NetworkingEngine.RequestType.KEY) {
keyRequests++;
}
});
await player.load('/base/test/test/assets/hls-aes-256/index.m3u8');
await video.play();
expect(player.isLive()).toBe(false);
Expand All @@ -83,6 +90,9 @@ describe('HlsParser', () => {
await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 10, 30);

await player.unload();

// The stream has 6 #EXT-X-KEY but only 5 different keys.
expect(keyRequests).toBe(5);
});

it('supports SAMPLE-AES identity streaming', async () => {
Expand Down
1 change: 0 additions & 1 deletion test/test/assets/hls-aes-256/media.m3u8
Expand Up @@ -4,7 +4,6 @@
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-KEY:METHOD=NONE
#EXT-X-KEY:METHOD=AES-256,URI="init.key",IV=0xF9EBE119F65FCF2E5F3FDEEB4A3EB3D5
#EXT-X-MAP:URI="init.mp4"

Expand Down

0 comments on commit ea740ba

Please sign in to comment.