-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: DRM API for V1 #2700
Comments
Ideally, I would rather we collaborate on a hypothetical |
I personally agree.
I would also request if it's not already available, is the EXT-X-MAP tag and/or any PSSH info associated with the KEY. Specifically, as you mentioned this is required for
|
Providing access to events and data required by a DRM implementation makes sense. These are great suggestions.
Here's where I differ, because think we could still offer solutions for different systems. We don't need to include everything in the main bundle. We could output a different target or perform code splitting with webpack if size is really a concern. I know it's more about maintainability. I would love to know how many users are taking advantage of the Widevine features built in - outside of contributors. If we were to remove the widevine eme-controller from v1, it would be great to move the implementation rather than remove it, as a sample implementation of the methods and events discussed here. I would miss watching the clip of Angel One in the demo page without it! 😉 |
Absolutely.
Yes!
100%, not planning on throwing away the working code that users / contributors have wanted and written, but changing how a user interacts with it, and therefore our ability to change it. My main goal is to stop the spread of configuration growth in relation to DRM for the core hls.js API. I'm not against offering a code-split module (that is even embedded in the full build) to accomplish DRM playback built-atop the proposed "I've encountered DRM content" hook, I just don't believe we need to ship with the EME handshake in a core controller. Here's the future bare-minimum configuration options I'm aware of if we continue down the current path.
|
To be clearer, I wasn't planning on parsing the init segment itself looking for PSSH boxes, as the EME implementation on the browser should surface the PSSH box out of the init segment itself. But instead, make the PSSH information in EXT-X-KEY tags available. This way manifest based PSSH information would be available to a user in the exposed read-only APIs, and the segment based PSSHs would be exposed via the EME flow. These two mechanisms would be combined into a single notification that the content you have requested for playback is encrypted, and requires media keys. Am I missing something else with regards to EXT-X-MAP?
To make sure it's very clear: this is where I see a user being able to slot the implementation of our current EME code, but it would be moved outside of the core EMEController, and become its own standalone pure API. |
I would expect the PSSH from the EME as well but I believe we experienced a case where this did not occur and we needed to do some parsing ourselves. Matthew, can you confirm or does this look good? |
100% for the code-splitting alternative embedded inside the core module that would load if EME is enabled per configuration and DRM is detected inside the manifest / stream. If we were to build a DRM.js lib (offered alongside hls.js core module), we would still need the x configuration and hooks to http requests / initData transformation, ... etc (shaka is great on that point). |
One problem I see with splitting EME management out of hls.js is that, as has been noted, certain vendors' DRM configurations are reliant on HLS playlists. So, just in the way HLS playlists govern media playback via MSE, they could also govern DRM media playback via EME. To me, this would make it seem like configuration of EME would be within the scope of hls.js.
I agree that hls.js should at least agree to provide any data from an
I understand the concern that supporting different vendors' various DRM configurations could present a challenge as they can be so varied. However, conforming tightly with the EME API would allow us to provide built-in support for DRM while creating an extensible system for different vendors' configurations that would not block a user from using a custom DRM config, but also allow a user to leverage hls.js to reduce boilerplate overhead for supported DRM configs. In our fork of hls.js (PR to
The hooks pass the user any available information for each step in the Promise chain, but also allow for custom configuration if desired. The hooks we provided are:
The benefit of the hook-based DRM configuration system is that it allows the user to adapt to vendor-specific DRM configurations for each step of the EME configuration Promise chain, especially providing Overall, I believe that managing EME is within the scope of hls.js and would be a powerful feature to provide in the v1.0.0 release. While there are many different vendors' DRM configurations, if we conform tightly to the EME API, handle the boilerplate configuration internally, and allow the user to provide hooks to handle vendor-specific DRM implementations, we could include DRM-protected content playback as a feature of hls.js. |
^ in lieu of a premature PR, here is the EME controller adaptation that we wrote in our fork that implements the described hooks |
@realeyes-matthew thank you for the consideration! I think it's clear that I'm in the minority for wanting to strip the EME handshake out of hls.js. So, Thank you everyone for the input! I think it's better that we move forward together, and I can understand the benefit of the simplicity of including the EME handling inside hls.js, so let's go towards that single goal. I've left a new comment below with the next step towards adding support for manifest-based DRM keys. If anyone has preferences on how we handle the priority between EME signalled and Manifest signalled DRM, more input would be appreciated there! |
First step: #2735 Intention here is to start to populate the internal data model with the information we need to populate the public levelKeys API. So, adding parsing for the manifest signalled DRM keys. Currently, since we don't have code that supports them their skipped. |
Now that #2735 is merged, the Fragment class During the implementation of this, something I didn't address was multi-drm streams. Currently the data model assumes one MultiDRM manifests I have found are relatively common and currently are unsupported due to the fact that we only store a single level key on a fragment. This will need to change if we want to support manifest delivered keys in a multi-keysystem manifest. I'm currently focused on stamping out any issues that may be stemming from rollover PTS handling. If someone wanted to take on switching our key handling to be array based for After we update the data model from a AES-128 Identity key centric style to support a DRM case, I see the steps roughly as;
|
Closing this issue in favor of a new one with the direction above. |
Is your feature request related to a problem? Please describe.
As I've been going through the various DRM CDM's and their respective implementations with different vendors, and then the supporting mechanisms for EME, it's become increasingly clear to me that each vendor / organizational unit can utilize different mechanisms provided by these specifications for storing information in the media, or in the HLS manifest, and it would be an increasingly difficult support task for hls.js to accommodate these one-off scenarios in a generic way. Leading me to wonder if the current API in hls.js will be something that we want to freeze with V1.
Describe the solution you'd like
Old proposal for pushing EME outside of the core hls.js controllers
What I'm thinking about would be a more generic and extensible API in V1.
We commit to offering a read-only API that exposes manifest level key information that we parse out of the manifest.
The intention here is to surface:
skd://
data for Fairplay.This information would be stored when manifest was parsed, and available from an Hls instance. Bikeshed on naming, but I would think of offering two specific property-based getter APIs.
sessionKeys
-#EXT-X-SESSION-KEY
levelKeys
(perhaps akeys
attribute on exposed level) -#EXT-X-KEY
in a levelThese properties would return the parsed structure for their respective tags.
I prefer the specific API over a generic parsed manifest structure being exposed because we can offer stronger guarantees on the API.
Here's the kicker I want to propose. We rollback the current public API support beyond what I've outlined above for DRM. This would mean deprecating the widevine config, license URL.
Hls.js at least as how I perceive it is intended to extend and offer support to the MSE API to parse and playback HLS content. Beyond offering metadata from the HLS manifest I start to think of the EME integration as slightly out of scope, given what I've laid out above, we have given the user all the information they need to be able to create an implementation for their CDM, without locking an API design in, or how to parse and set up MediaKeys for the media element.
Describe alternatives you've considered
I hesitate to offer any implementations that are not easily removed if building from source, this is because of the earlier described vendor specifics I've seen, requiring rather extensive hooks into the flow if you want to support all variations.
An extension on the above idea is offering a much simpler extension API to the "encrypted" media event listener, that is fired when sessionKey / levelKeys is populated, or the HTML5 encrypted event is fired. This would be fired for both cases. If from an encrypted event, it would include the source event, otherwise it would be undefined, and the user would be able to hook their code to this.
This is an alternative because it brings us closer to bringing the DRM handling into the library, which I'm not sure is something to freeze into the V1 API since it will mean a lot of code written and part of the bundle, that will only be useful for a minority set of users.
Perhaps if we offered CDM implementations as pure functions outside of the core class Hls.js and iterated there it would lend itself to having smaller bundle sizes automatically for folks who built from source, and we could include them as static methods in the "full" distribution. Something to discuss there.
Context
The implementations we've seen over the last year for how to accomplish DRM have taken wildly different approaches, manifest-driven, encrypted event driven, including init data parsing, passthrough handling of init data, what configuration do you use for codec information when requesting CDM support? This is the variation I'm talking about in business rules and the deployment to handling specific CDM implementations. Depending on who they talk with, and who their vendor is, they are given different recommendations for the best way to work.
I don't know if we would ever get to a point with an API that pleased everyone, and the other side of users would end up with a larger library they didn't need, or much more complicated build-processes.
#2665 - navigator API, needing more control
#2664 - cleanup of media key sessions
#2630 - adding a new CDM (fairplay)
#1918 - adding a new CDM (playready)
#2194 - switching to manifest-driven encrypted events
#1915 - parsing initdata from manifest
#1442 - initial implementation
From #1442...
Given the input below, I think this is the API we want to freeze with for V1. I'm retracting this proposal, and will open a new issue to get manifest-delivered DRM supported for V1 API.
The text was updated successfully, but these errors were encountered: