Skip to content

Commit

Permalink
Support AES-128 Encrypted Low-Latency HLS Parts (#5214)
Browse files Browse the repository at this point in the history
  • Loading branch information
robwalch committed Feb 7, 2023
1 parent ab06d97 commit 19e489e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 21 deletions.
3 changes: 3 additions & 0 deletions src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ export default class BaseStreamController
keyLoadingPromise = this.keyLoader.load(frag).then((keyLoadedData) => {
if (!this.fragContextChanged(keyLoadedData.frag)) {
this.hls.trigger(Events.KEY_LOADED, keyLoadedData);
if (this.state === State.KEY_LOADING) {
this.state = State.IDLE;
}
return keyLoadedData;
}
});
Expand Down
7 changes: 0 additions & 7 deletions src/crypt/decrypter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,6 @@ export default class Decrypter {
public flush(): Uint8Array | null {
const { currentResult, remainderData } = this;
if (!currentResult || remainderData) {
logger.error(
`[softwareDecrypt] ${
remainderData
? 'overflow bytes: ' + remainderData.byteLength
: 'no result'
}`
);
this.reset();
return null;
}
Expand Down
7 changes: 6 additions & 1 deletion src/demux/transmuxer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,16 @@ export default class Transmuxer {
if (decrypter.isSync()) {
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
// data is handled in the flush() call
const decryptedData = decrypter.softwareDecrypt(
let decryptedData = decrypter.softwareDecrypt(
uintData,
keyData.key.buffer,
keyData.iv.buffer
);
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
const loadingParts = chunkMeta.part > -1;
if (loadingParts) {
decryptedData = decrypter.flush();
}
if (!decryptedData) {
stats.executeEnd = now();
return emptyResult(chunkMeta);
Expand Down
36 changes: 23 additions & 13 deletions src/loader/m3u8-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,19 +404,7 @@ export default class M3U8Parser {
if (Number.isFinite(frag.duration)) {
frag.start = totalduration;
if (levelkeys) {
frag.levelkeys = levelkeys;
const { encryptedFragments } = level;
if (
frag.levelkeys &&
Object.keys(frag.levelkeys).some(
(format) => frag.levelkeys![format].isCommonEncryption
) &&
(!encryptedFragments.length ||
encryptedFragments[encryptedFragments.length - 1].levelkeys !==
levelkeys)
) {
encryptedFragments.push(frag);
}
setFragLevelKeys(frag, levelkeys, level);
}
frag.sn = currentSN;
frag.level = id;
Expand Down Expand Up @@ -717,6 +705,9 @@ export default class M3U8Parser {
assignProgramDateTime(frag, prevFrag);
frag.cc = discontinuityCounter;
level.fragmentHint = frag;
if (levelkeys) {
setFragLevelKeys(frag, levelkeys, level);
}
}
const fragmentLength = fragments.length;
const firstFragment = fragments[0];
Expand Down Expand Up @@ -887,3 +878,22 @@ function setInitSegment(
}
frag.initSegment = null;
}

function setFragLevelKeys(
frag: Fragment,
levelkeys: { [key: string]: LevelKey },
level: LevelDetails
) {
frag.levelkeys = levelkeys;
const { encryptedFragments } = level;
if (
(!encryptedFragments.length ||
encryptedFragments[encryptedFragments.length - 1].levelkeys !==
levelkeys) &&
Object.keys(levelkeys).some(
(format) => levelkeys![format].isCommonEncryption
)
) {
encryptedFragments.push(frag);
}
}

0 comments on commit 19e489e

Please sign in to comment.