videojs/videojs-contrib-hls — pull request #139 by dmlap (2014-08-22 14:23:42+00:00)
Title: Support segment-level AES-128 encryption

Add the ability to decrypt and play the most common form of encrypted HLS streams. Uses a modified version of the AES-128 block cipher from the [Stanford Javascript Crypto Library](https://github.com/bitwiseshiftleft/sjcl) and a new [pkcs7 module](https://github.com/brightcove/pkcs7) for padding. Cipher block chaining is implemented inline.

Keys are sequentially requested in the order they appear in the playlist, in parallel with segment requests. Since they're tiny, we fetch them as quickly as possible. Key request failures are retried once in the case of an error and then we give up and skip any segments that cannot be decrypted as a result. Duplicate key declarations in the playlist generate multiple key requests and we do not share key data across playlists, either.

Preliminary performance testing indicates decryption takes an order of magnitude more time than transmuxing. I suspect this is because of the input transformations we have to perform to get our nice typed-array segment data into a format that the crypto code can work with. The extra cycles aren't particularly noticeable on my machine and I suspect there are easy optimizations that we can make in this area.