video.js icon indicating copy to clipboard operation
video.js copied to clipboard

Cannot play SAMPLE-AES nor Segment AES fMP4 using VHS 2.2 non-native

Open RafalLukawiecki opened this issue 5 years ago • 28 comments

Description

When playing back fMP4 HLS H264 stream that has both audio and video AES-Sample or AES-Segment encrypted using Apple mediafilesegmenter an uncaught exception is thrown in non-native playback using Chrome and Firefox. Safari plays back without any problems.

Steps to reproduce

  1. Using hosted VHS 2.2.0 player at https://videojs-http-streaming.netlify.app/ try playing Sample encrypted stream at https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-sample-aes/m.m3u8
  2. Try playing Segment encrypted https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-segment-aes/m.m3u8

Results

Expected

Normal playback.

Actual

Uncaught exception, and player hangs indefinitely.

Error output

Chrome:

Uncaught RangeError: byte length of Int32Array should be a multiple of 4
    at new Int32Array (<anonymous>)
    at new Decrypter (e078b76d-d433-48ec-a7ba-90c3f96bd0d8:548)
    at DecrypterWorker.self.onmessage (e078b76d-d433-48ec-a7ba-90c3f96bd0d8:647)
Decrypter @ e078b76d-d433-48ec-a7ba-90c3f96bd0d8:548
DecrypterWorker.self.onmessage @ e078b76d-d433-48ec-a7ba-90c3f96bd0d8:647

Firefox:

RangeError: attempting to construct out-of-bounds TypedArray on ArrayBuffer 95ef2b78-e7e8-ef4b-8ff6-a0491701a31e:548:29
    Decrypter blob:https://videojs-http-streaming.netlify.app/95ef2b78-e7e8-ef4b-8ff6-a0491701a31e:548
    onmessage blob:https://videojs-http-streaming.netlify.app/95ef2b78-e7e8-ef4b-8ff6-a0491701a31e:647

Additional Information

versions

videojs

7.8.3

browsers

Chrome 86, Firefox 81

OSes

macOS 10.15.7

plugins

vhs 2.2.0

RafalLukawiecki avatar Oct 14 '20 14:10 RafalLukawiecki

Unfortunately, SAMPLE-AES isn't supported right now.

gkatsev avatar Oct 14 '20 16:10 gkatsev

Thank you. Let me retest with segment AES.

RafalLukawiecki avatar Oct 14 '20 16:10 RafalLukawiecki

I am afraid it won't play segment AES either. Please have a look at this stream: https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-segment-aes/m.m3u8 using your hosted player.

In Chrome the error is:

Uncaught TypeError: Cannot read property 'video' of undefined
    at handleSegmentBytes (videojs-http-streaming.js:9497)
    at Worker.decryptionHandler (videojs-http-streaming.js:9650)
handleSegmentBytes @ videojs-http-streaming.js:9497
decryptionHandler @ videojs-http-streaming.js:9650

In Firefox the error is:

Uncaught TypeError: tracks is undefined

Is this a problem with my stream or VHS/video.js? I am happy to provide more info if that helps.

PS. It plays in Safari without any issues.

RafalLukawiecki avatar Oct 14 '20 16:10 RafalLukawiecki

AES-128 should work. We test it on a regular basis https://videojs-http-streaming.netlify.app/?debug=false&autoplay=false&muted=false&minified=false&liveui=false&partial=false&url=https%3A%2F%2Fplayertest.longtailvideo.com%2Fadaptive%2Foceans_aes%2Foceans_aes.m3u8&type=application%2Fx-mpegurl&keysystems=&buffer-water=false However, it's definitely possible that there's some kind of bug there.

gkatsev avatar Oct 14 '20 16:10 gkatsev

That does not look like fragmented MP4 but more like MPEG-TS. Are you testing AES with fMP4? Please have a look at the stream I shared (https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-segment-aes/m.m3u8) to see if it plays for you. Do you think the issue is with my stream or VHS/VJS?

If it would be helpful, I can encode a few of those problematic fMP4 test streams so that you can see the issues on an ongoing basis.

RafalLukawiecki avatar Oct 14 '20 16:10 RafalLukawiecki

I have retested just now using video.js 7.10.1 and the built-in VHS 2.2.3 and I am afraid Segment-AES still does not work for fMP4 containers.

RafalLukawiecki avatar Oct 15 '20 15:10 RafalLukawiecki

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 25 '20 11:12 stale[bot]

Still an issue with videojs 7.11.0 and vhs 2.4.1:

  • Cannot play SEGMENT-AES: https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-segment-aes/m.m3u8
  • Cannot play SAMPLE-AES: https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-sample-aes/m.m3u8

RafalLukawiecki avatar Jan 07 '21 11:01 RafalLukawiecki

Hey! We've detected some video files in a comment on this issue. If you'd like to permanently archive these videos and tie them to this project, a maintainer of the project can reply to this issue with the following commands:

  • for https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-segment-aes/m.m3u8: say @video-archivist-bot save zEpzwd
  • for https://d2gw5qqm1tusud.cloudfront.net/pml-test-fmp4-sample-aes/m.m3u8: say @video-archivist-bot save 9E3gE0

video-archivist-bot avatar Jan 07 '21 11:01 video-archivist-bot

Unfortunately, we don't support SAMPLE-AES at all right now, and it does seem like we never got AES-128 working with fmp4 segments rather than TS segments.

gkatsev avatar Jan 07 '21 15:01 gkatsev

@RafalLukawiecki we were facing the same issue. After some trial and error, I figured out that the initiation vector seems to be the issue. I simply encoded our files with an empty string as an initiation vector and made sure to pass an empty IV to the playlist file:

#EXT-X-KEY:METHOD=AES-128,URI="pb-alpha-9cdffa16bbd5ccf0-0.key",IV=

Hope it helps.

Freddy

freddyamsterdam avatar Jan 12 '21 14:01 freddyamsterdam

Interesting, @freddyamsterdam. I will try encoding a new video with an empty IV to see if that helps with our streams. In any case, if that works it would suggest there is a problem with how the IV value is read or used with fMP4 segments in video.js, which could be a good debugging hint. Thanks.

RafalLukawiecki avatar Jan 12 '21 18:01 RafalLukawiecki

@RafalLukawiecki it doesn't seem to work with multiple representation playlists. 😞 Will post an update if I manage to make any progress.

freddyamsterdam avatar Jan 12 '21 19:01 freddyamsterdam

Oh, interesting that it works with an empty IV. It definitely works with ts segments, I wonder what's there that's failing for fmp4 segments.

gkatsev avatar Jan 21 '21 17:01 gkatsev

@gkatsev didn't mention before, but we're using TS segments 😢

freddyamsterdam avatar Jan 21 '21 17:01 freddyamsterdam

@freddyamsterdam TS segments should work with IV properly. Did you find it didn't? If so, can you open a separate issue? And if you're able to provide a sample stream, that would be awesome.

gkatsev avatar Jan 21 '21 17:01 gkatsev

Thank you, both, for following up. I am unsure if and what I can do to help troubleshoot it further. The test stream is still available.

RafalLukawiecki avatar Jan 21 '21 18:01 RafalLukawiecki

@gkatsev sure thing!

@RafalLukawiecki did the empty IV not work out for you?

freddyamsterdam avatar Jan 21 '21 18:01 freddyamsterdam

So sorry, I have not rendered another test stream with an empty IV, yet. I will do that.

RafalLukawiecki avatar Jan 21 '21 18:01 RafalLukawiecki

The issue with fMP4 appears to be that the init segments are not being decrypted in http-streaming. This also explains why TS works but fMP4 does not, since init segments are only used for fMP4 but not for TS.

The example2.zip reproducer in https://github.com/videojs/video.js/issues/7051 shows that encrypting the init segment works with the Apple native decoder. Also the HLS spec (RFC 8216) notes that the init segments are encrypted: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4.4.4.4

I started writing a patch but I suspect someone more familiar with the project might be able to fix this faster/better.

iroha7941 avatar Jan 21 '21 18:01 iroha7941

@iroha7941, unless someone else comes up with a solution, I would be happy to help test your patch.

RafalLukawiecki avatar Jan 21 '21 19:01 RafalLukawiecki

@iroha7941 oh, that makes a lot of sense. We probably didn't think that the init segments could also be encrypted when we added fmp4 support, and we didn't have any test content back then. If you're able to provide a patch that would be amazing! We'll happily review and help out, feel free to ask questions in the #playback channel on our slack: http://slack.videojs.com

gkatsev avatar Jan 21 '21 20:01 gkatsev

I created patches for http-streaming and m3u8-parser that enable video.js to playback the encrypted fMP4 files I've created. I created a repo containing a patched build of video.js and links to the branches in my forked repos which contain the patches: https://github.com/iroha7941/video.js-build

I have not yet done a lot of testing (and I haven't really tested for byte-range segments), and am still having problems running unit tests for http-streaming, but this seems to work for me.

iroha7941 avatar Jan 31 '21 00:01 iroha7941

@iroha7941 I finally got around to looking at the m3u8-parser PR and didn't see it working with my local VHS copy, then I noticed that you had VHS related changes as well. Is there a reason why you didn't make a PR for it? Is it because it's multiple commits behind main? I can confirm that your changes do work.

gkatsev avatar Feb 17 '21 17:02 gkatsev

@gkatsev I hadn't created a PR for VHS as I still haven't been able to run testsuite successfully (many tests fail with "vhs is undefined"), let alone add appropriate tests. I'm guessing this is just a problem with my setup or something (I'm still new to Javascript/npm development), but I haven't had time to look into it more. When I have a patch with appropriate tests ready I'll sumbit a PR. Sorry for the delay.

iroha7941 avatar Mar 01 '21 22:03 iroha7941

If you make a PR we can try and help figure out what's wrong. Either way, thanks!

gkatsev avatar Mar 01 '21 22:03 gkatsev

Hi @gkatsev, did you get to play SAMPLE-AES encrypted fmp4 files with HLS?

index23 avatar May 19 '22 10:05 index23

@iroha7941 I have the same question. I encrypt every of my ABR tracks with a different SAMPLE-AES key and pass it to the m3u8 playlist of that specific track. Sadly, I also don't get VideoJS to play the Stream :( Would be awesome to finally see this feature

venomone avatar Jul 18 '22 00:07 venomone