Dash-Industry-Forum / dash.js

A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.
http://reference.dashif.org/dash.js/nightly/samples/dash-if-reference-player/index.html
Other
5.1k stars 1.67k forks source link

Use AES128 encryption and keyUriTemplate #1993

Open HugoCrd opened 7 years ago

HugoCrd commented 7 years ago

Hi!

Here's a question about how to use AES encryption (from Azure) with Dash.js. Can't find out if it's a supported feature or not.

Thanks a lot for your work!

Environment
Steps to reproduce
  1. Go to http://dashif.org/reference/players/javascript/v2.5.0/samples/dash-if-reference-player/index.html

  2. Use http://melusynsandbox-melusynsandbox.streaming.mediaservices.windows.net/178b0989-5e2f-4f56-8516-9ddabc28ce1a/big_buck_bunny_480p_2mb.ism/manifest(format=mpd-time-csf)

This MPD contains:

<ContentProtection schemeIdUri="urn:mpeg:dash:sea:2012">
        <sea:SegmentEncryption schemeIdUri="urn:mpeg:dash:sea:aes128-cbc:2013"/>
        <sea:KeySystem keySystemUri="urn:mpeg:dash:sea:keysys:http:2013"/>
        <sea:CryptoPeriod keyUriTemplate="https://melusynsandbox.keydelivery.mediaservices.windows.net/?kid=297665ac-80af-4389-b20f-81b492b0a7c3" IV="0xCDBA0622C3EFACFDF52735D6D3DCA62F"/>
</ContentProtection>
  1. Media resource could not be decoded
Observed behaviour

Dash does not seem to understand where to get AES key to decode the stream.

I saw here that that kind of thing was allowed: https://github.com/Dash-Industry-Forum/Conformance-and-reference-source/blob/master/conformance/MPDCrypto/test/input/encrypted/future_work/test2_protected.mpd

No request to https://melusynsandbox.keydelivery.mediaservices.windows.net/?kid=297665ac-80af-4389-b20f-81b492b0a7c3 was made

Console output
[8] EME detected on this user agent! (ProtectionModel_21Jan2015)   Debug.js:127:12
[9] [dash.js 2.5.0] MediaPlayer has been initialized   Debug.js:127:12
[3813] Playback Initialized   Debug.js:127:12
XML Parsing Error: syntax error
Location: http://mediapm.edgesuite.net/dash/public/nightly/samples/dash-if-reference-player/index.html
Line Number 1, Column 1:  index.html:1:1
[3913] Parsing complete: ( xml2json: 7.20ms, objectiron: 7.49ms, total: 0.0147s)   Debug.js:127:12
[3917] SegmentTimeline detected using calculated Live Edge Time   Debug.js:127:12
[3921] MediaSource attached to element.  Waiting on open...   Debug.js:127:12
[3922] Manifest has been refreshed at Wed Jun 07 2017 11:15:21 GMT+0200 (CEST)[1496826921.545]    Debug.js:127:12
[3925] Native video element event: ratechange:  1   Debug.js:127:12
[3925] MediaSource is open!   Debug.js:127:12
[3925] Duration successfully set to: 15.424   Debug.js:127:12
[3926] Added 0 inline events   Debug.js:127:12
[3928] video codec: video/mp4;codecs="avc1.64000D"   Debug.js:127:12
[3938] AbrController (video) switch from 0 to 2/3 (buffer: 0)
undefined   Debug.js:127:12
[3950] audio codec: audio/mp4;codecs="mp4a.40.2"   Debug.js:127:12
[3954] No text data.   Debug.js:127:12
[3955] No fragmentedText data.   Debug.js:127:12
[3955] No embeddedText data.   Debug.js:127:12
[3955] No muxed data.   Debug.js:127:12
[3959] Schedule controller starting for video   Debug.js:127:12
[3959] Schedule controller starting for audio   Debug.js:127:12
[3960] Start Event Controller   Debug.js:127:12
[3977] Top qualityvideo index has changed from undefined to 3   Debug.js:127:12
[3979] AbrController (video) stay on 2/3 (buffer: 0)   Debug.js:127:12
[3987] Top qualityaudio index has changed from undefined to 0   Debug.js:127:12
[3988] AbrController (audio) stay on 0/0 (buffer: 0)   Debug.js:127:12
[3991] Native video element event: play   Debug.js:127:12
[3992] Native video element event: playing   Debug.js:127:12
[4055] Init fragment finished loading saving to audio's init cache   Debug.js:127:12
Media resource blob:http://mediapm.edgesuite.net/1d9f1733-bbd2-f749-b2de-2c29e0ac65af could not be decoded.  index.html
[4056] Caught pending play exception - continuing (NotSupportedError: The media resource indicated by the src attribute or assigned media provider object was not suitable.)   Debug.js:127:12
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable  MediaSourceController.js:74:44
[4058] Video Element Error: MEDIA_ERR_SRC_NOT_SUPPORTED   Debug.js:127:12
[4059] [object MediaError]   Debug.js:127:12
mediasource : undefined  main.js:210:9
[4061] Schedule controller stopping for video   Debug.js:127:12
[4061] Schedule controller stopping for audio   Debug.js:127:12
[4065] Native video element event: ratechange:  1   Debug.js:127:12
[9208] Requesting seek to time: 3.55   Debug.js:127:12
[9554] Requesting seek to time: 2.58   Debug.js:127:12
[10380] Requesting seek to time: 9.29   Debug.js:127:12
[11141] Requesting seek to time: 0   Debug.js:127:12

Thanks a lot! Best,

davemevans commented 7 years ago

dash.js doesn't support AES encryption of whole segments. MPEG Common Encryption is supported on platforms where EME is available.

I don't know the DASH-IF position on this, so I'm not sure if it would be a feature that would ever be added. Perhaps @wilaw or similar can comment then either close or label as appropriate.

wilaw commented 7 years ago

None of the current DASH interop points (DASH IF, DVB DASH, HbbTV) support envelope encryption, so the drive to add this would not come from DASh IF. However, I'm all for dash.js serving the market, in addition to being a reference player. So if there is market demand to support this Azure implementation of urn:mpeg:dash:sea:aes128-cbc:2013, then we should add it. I'd prefer it was added behind a general flag, along the lines of "dashifcompliant". This can be set true by default, but it could be turned off to enable useful features like muxed A/V content and envelope encryption.

Adding some external reference https://docs.microsoft.com/en-us/azure/media-services/media-services-protect-with-aes128, keeping this issue open and re-labeling as feature request.

I'll also ask Microsoft is they are willing to do the work to support this.

southworkschaied commented 4 years ago

Any updates on this feature? Thanks!

beaconskartik commented 4 years ago

Any updates on supporting AES-128-CBC?

azeemmohd commented 4 years ago

Hi,

When using AES ClearKey, does the DASH protocol mandate putting the key acquisition url in the manifest or make it optional, as I see that some players like Exoplayer allow keys to be configured with the keys direclty like so:

player.configure({
    drm: {
      clearKeys: {
        '91341951696b5e1ba232439ecec1f12a': '0a247b0751cbf1a827e2fedfb87479a2'
      }
    }
  });
dsilhavy commented 4 years ago

@azeemmohd dash.js allows you to set the keys via the API as well:

    function init() {
        const protData = {
            "org.w3.clearkey": {
                "clearkeys": {
                    "nrQFDeRLSAKTLifXUIPiZg": "FmY0xnWCPCNaSpRG-tUuTQ"
                }
            }
        };
        var video,
            player,
            url = "https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_ClearKey.mpd";

        video = document.querySelector("video");
        player = dashjs.MediaPlayer().create();
        player.initialize(video, url, true);
        player.setProtectionData(protData);
    }
kunalgoelgh commented 4 years ago

@dsilhavy Can we use a custom license delivery url in dash.js instead of providing AES key directly?

Tried: var laUrl = 'https://protectionkey.free.beeceptor.com/my/api/path'; player.setProtectionData({ "org.w3.clearkey": { "serverURL" : laUrl } //"org.w3.clearkey": { "clearkeys": { "QyFWeBI0EjQSNBI0EjQSNA":"EjQSNBI0EjQSNBI0EjQSNA" } } // KID=KEY });

Here, the dash.js player doesn't invoke the LAUrl at all, and video play doesn't start even though all segments are fetched. There are no errors thrown either in browser console. (On using Inspect)

Murmur commented 4 years ago

See this example for ClearkeyDRM(Firefox,Chrome) with LaUrl address, so in the end this is using a similar to Playready and Widevine systems would use. https://m.dtv.fi/dash/index_clearkey2.html?video=33

Study this script how to handle clearkey license request, script has a hardcoded KID=KEY lookup list but you should get the idea. Also F12 debug firefox-chrome http requests to see http payloads. https://github.com/HbbTV-Association/ReferenceApplication/blob/master/tools/test/laurl_ck.php

You should not signal any other <ContentProtection> DRM in a manifest, just a generic CENC marker and ClearkeyDRM elements should be found. Player may still use playready or widevine if found in a manifest.

kunalgoelgh commented 4 years ago

Thanks.

@Murmur \ All

Is it possible to 1) Read LaUrl from MPD file for ClearKey instead of Application\System specific settings to the player? (And is this ability implemented as a choice by players?)

We wanted to explore if the manifest file can be the source of truth, so that any additional params are not required to passed to the player separately.

The DashIF and W3C documentation calls out for LaUrl to be provided via MPD when SystemId: e2719d58-a985-b3c9-781a-b030af78d30e is used.

Tried the same, but the LaUrl is not being picked up from MPD file.

  <!-- Clear Key -->
  <ContentProtection schemeIdUri="urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e" value="ClearKey1.0">
    <clearkey:Laurl Lic_type="EME-1.0">https://protectionkey.free.beeceptor.com/my/api/path</clearkey:Laurl>
    <dashif:laurl>https://protectionkey.free.beeceptor.com/my/api/path</dashif:laurl>
  </ContentProtection>