video-dev / hls.js

HLS.js is a JavaScript library that plays HLS in browsers with support for MSE.
https://hlsjs.video-dev.org/demo
Other
14.82k stars 2.57k forks source link

Playing H264 fmp4 aes encrypted video #6226

Closed YannickFuereder closed 8 months ago

YannickFuereder commented 8 months ago

What do you want to do with Hls.js?

Hey,

i am trying to play a Fragmented, Aes 128 CBC encrypted video using hlsjs. Video playback works fine in Firefox and ffplay however Chrome/Safari throw an error.

Error:

Buffer appending error
Buffer append error
A media error occurred: bufferAppendError

Test Stream (works in firefox but not in chrome): https://hlsjs.video-dev.org/demo/?src=https%3A%2F%2Fcdn.netdb.at%2Fhub%2Ftesthlsenc%2Fmaster.m3u8&demoConfig=eyJlbmFibGVTdHJlYW1pbmciOnRydWUsImF1dG9SZWNvdmVyRXJyb3IiOnRydWUsInN0b3BPblN0YWxsIjpmYWxzZSwiZHVtcGZNUDQiOmZhbHNlLCJsZXZlbENhcHBpbmciOi0xLCJsaW1pdE1ldHJpY3MiOi0xfQ==

ffplay command: ffplay -i "https://cdn.netdb.at/hub/testhlsenc/master.m3u8"

I am guessing that there is something wrong with my init.mp4. How do i find out what it is?

What have you tried so far?

No response

robwalch commented 8 months ago

Playback errors in Safari with native HLS playback as well. In both cases (HLS.js and Safari HLS) we can see some video. Check that your playlist KEY tags are correct and verify decryption on the segment(s) that fail to append. Could be an issue with the encryption or missing/incorrect IV data for segments in the Playlist.

YannickFuereder commented 8 months ago

my iv i just an empty array (for testing purposes).

iv: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
iv_hex: 00000000000000000000000000000000

adding it to the playlist results in decryption errors i am using the same iv for all segments. Might this be the problem?

robwalch commented 8 months ago

Section 5.2 "IV for AES-128" of the HLS spec indicates that the Media Sequence is to be used when the IV attribute is missing https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-5.2

If the IV is identical you probably need to repeat the key tag for every segment to reset it.

YannickFuereder commented 8 months ago

did some more testing.

my current setup looks like this:

i have a video with 4 segments init.mp4 seg-2.m4s ...

all segments (including the init.mp4) are encoded using the same iv and key i also switched to a proper iv

i edited the playlist to reset the key/iv after every segment like you recommended

#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=2.0.0-641
#
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:7
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=2b7e151628aed2a6abf7158809cf4f3c
#EXT-X-MAP:URI="init.mp4"
#EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=2b7e151628aed2a6abf7158809cf4f3c
#EXTINF:6.08,
seg-1.m4s
#EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=2b7e151628aed2a6abf7158809cf4f3c
#EXTINF:4.0,
seg-2.m4s
#EXT-X-ENDLIST

now i get this error in the demo player

RangeError: offset is outside the bounds of the DataView

i dont think that there is a problem with my encryption since i can decrypt every segment without any inaccuracies to the original files

what does this range error mean?

robwalch commented 8 months ago

what does this range error mean?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError

robwalch commented 8 months ago

Try dev:

https://hlsjs-dev.video-dev.org/demo/

and verify whether software or cryto API is being used for decryption (set enableSoftwareAES: false in config on latest release):

https://github.com/video-dev/hls.js/blob/40b382b8f7a2c80a2fa3a94445ba0ad70e0cb7dc/src/demux/transmuxer.ts#L122-L148

YannickFuereder commented 8 months ago

I had to change my iv from '2b7e151628aed2a6abf7158809cf4f3c' to '0x2b7e151628aed2a6abf7158809cf4f3c' because the first 2 characters get lost somewhere before the decryption process