To present encrypted content a DASH client needs to:
- [[#CPS-selection-workflow|Select a DRM system that is capable of decrypting the content.]]
- During selection, [[#CPS-system-capabilities|the set of desired DRM system capabilities and the supported capabilities is examined]] to identify suitable candidate systems.
- [[#CPS-activation-workflow|Activate the selected DRM system and configure it to decrypt content.]]
- During activation, [[#CPS-license-request-workflow|acquire any missing content keys and the licenses that govern their use]].
- [[#CPS-unavailable-keys|Monitor for changes in the availability of content keys and in the content protection attributes of the media stream]] and take required action to ensure that playback can continue (e.g. live services may periodically change the [=content keys=], requiring new licenses to be obtained, or existing licenses can simply expire and need renewal).
This chapter defines the recommended DASH client workflows for interacting with [=DRM systems=] in these aspects.
A [=DRM system=] implemented by a client platform may only support playback of encrypted content that matches certain parameters (e.g. codec type and level). A DASH client needs to detect what capabilities each [=DRM system=] has in order to understand what adaptation sets can be presented and to make an informed choice when multiple [=DRM systems=] can be used.
- Playback of H.264 High profile up to level 4.0 at "low" robustness
- Playback of H.264 High profile level 4.1 at "low" robustness
- Playback of H.265 Main 10 profile up to level 5.2 at "low" robustness
- Playback of AAC at "low" robustness
- Unique user identification
- Session persistence
A typical [=media platform=] API such as EME [[!encrypted-media]] will require the DASH client to query the platform by supplying a desired capability set. The [=media platform=] will inspect the desired capabilities, possibly displaying a permissions prompt to the user (if sensitive capabilities such as unique user identification are requested), after which it will return a supported capability set that indicates which of the desired capabilities are available.
The DASH client presents a set of desired capabilities for each [=DRM system=] and receives a response with the supported subset.The exact set of capabilities that can be used and the data format used to express them in capability detection APIs are defined by the [=media platform=] API. A DASH client is expected to have a full understanding of the potentially offered capabilities and how they map to parameters in the MPD. Some capabilities may have no relation to the MPD and whether they are required depends entirely on the DASH client or [=solution-specific logic and configuration=].
To detect the set of supported capabilities, a DASH client must first determine the required capability set for each adaptation set. This is the set of capabilities required to present all the content in a single adaptation set and can be determined based on the following:
- Content characteristics defined in the MPD (e.g. codecs strings of the representations and the used [=protection scheme=]).
- [=Solution-specific logic and configuration=] (e.g. what [=robustness level=] is required).
Advisement: Querying for the support of different [=protection schemes=] is currently not possible via the capability detection API of Encrypted Media Extensions [[!encrypted-media]]. To determine the supported [=protection schemes=], a DASH client must assume what the CDM supports. A bug is open on W3C EME and a pull request exists for the ISOBMFF file format bytestream. In future versions of EME, this may become possible.
Some of the capabilities (e.g. required [=robustness level=]) are [=DRM system=] specific. The [=required capability set=] contains the values for all [=DRM systems=].
During [=DRM system=] selection, the [=required capability set=] of each adaptation set is compared with the supported capability set of a [=DRM system=]. As a result of this, each candidate [=DRM system=] is associated with zero or more adaptation sets that can be successfully presented using that [=DRM system=].
It is possible that multiple [=DRM systems=] have the capabilities required to present some or all of the adaptation sets. When multiple candidates exist, the DASH client SHOULD enable [=solution-specific logic and configuration=] to make the final decision.
Note: Some sensible default behavior can be implemented in a generic way (e.g. the [=DRM system=] should be able to enable playback of both audio and video if both media types are present in the MPD). Still, there exist scenarios where the choices seem equivalent to the DASH client and an arbitrary choice needs to be made.
The workflows defined in this document contain the necessary extension points to allow DASH clients to exhibit sensible default behavior and enable [=solution-specific logic and configuration=] to drive the choices in an optimal direction.
The MPD describes the [=protection scheme=] used to encrypt content, with the default_KID
values identifying the [=content keys=] required for playback, and optionally provides the default [=DRM system configuration=] for one or more [=DRM systems=] via ContentProtection
descriptors. It also identifies the codecs used by each representation, enabling a DASH client to determine the set of required [=DRM system=] capabilities.
Neither an initialization segment nor a media segment is required to select a [=DRM system=]. The MPD is the only component of the presentation used for [=DRM system=] selection.
<AdaptationSet>
<ContentProtection
schemeIdUri="urn:mpeg:dash:mp4protection:2011"
value="cenc"
cenc:default_KID="34e5db32-8625-47cd-ba06-68fca0655a72" />
<ContentProtection
schemeIdUri="urn:uuid:d0ee2730-09b5-459f-8452-200e52b37567"
value="FirstDrm 2.0">
<cenc:pssh>YmFzZTY0IGVuY29kZWQgY29udGVudHMgb2YgkXBzc2iSIGJveCB3aXRoIHRoaXMgU3lzdGVtSUQ=</cenc:pssh>
<dashif:authzurl>https://example.com/tenants/5341/authorize?mode=firstDRM</dashif:authzurl>
<dashif:authzurl>https://alternative.example.com/tenants/5341/authorize?mode=firstDRM</dashif:authzurl>
<dashif:laurl>https://example.com/AcquireLicense</dashif:laurl>
<dashif:laurl>https://alternative.example.com/AcquireLicense</dashif:laurl>
</ContentProtection>
<ContentProtection
schemeIdUri="urn:uuid:eb3841cf-d7e4-4ec4-a3c5-a8b7f9f4f55b"
value="SecondDrm 8.0">
<cenc:pssh>ZXQgb2YgcGxheWFibGUgYWRhcHRhdGlvbiBzZXRzIG1heSBjaGFuZ2Ugb3ZlciB0aW1lIChlLmcuIGR1ZSB0byBsaWNlbnNlIGV4cGlyYXRpb24gb3IgZHVl</cenc:pssh>
<dashif:authzurl>https://example.com/tenants/5341/authorize?mode=secondDRM</dashif:authzurl>
</ContentProtection>
<Representation mimeType="video/mp4" codecs="avc1.64001f" width="640" height="360" />
<Representation mimeType="video/mp4" codecs="avc1.640028" width="852" height="480" />
</AdaptationSet>
</xmp>
The MPD provides [=DRM system configuration=] for [=DRM systems=]:
- For
FirstDRM
, the MPD provides complete [=DRM system configuration=], including the optionaldashif:authzurl
. Two equivalent alternative URLs are provided for accessing the associated services. - For
SecondDRM
, the MPD does not provide the license server URL. It must be supplied at runtime.
There are two encrypted representations in the adaptation set, each with a different codecs string. Both codecs strings are included in the [=required capability set=] of this adaptation set. A [=DRM system=] must support playback of both representations in order to present this adaptation set.
In addition to the MPD, a DASH client can use [=solution-specific logic and configuration=] for controlling DRM selection and configuration decisions (e.g. loading license server URLs from configuration data instead of the MPD). This is often implemented in the form of callbacks exposed by the DASH client to an "app" layer in which the client is hosted. It is assumed that when executing any such callbacks, a DASH client makes available relevant contextual data, allowing the business logic to make fully informed decisions.
The purpose of the [=DRM system=] selection workflow is to select a single [=DRM system=] that is capable of decrypting a meaningful subset of the adaptation sets selected for playback. The selected [=DRM system=] will meet the following criteria:
- It is actually implemented by the [=media platform=].
- It supports a set of capabilities sufficient to present an acceptable set of adaptation sets.
- The necessary [=DRM system configuration=] for this [=DRM system=] is available.
It may be that the selected [=DRM system=] is only able to decrypt a subset of the encrypted adaptation sets selected for playback. See also [[#CPS-unavailable-keys]].
The set of adaptation sets considered during selection does not need to be constrained to a single period, potentially enabling seamless transitions to a new period with a different set of [=content keys=].
In live services new periods may be added over time, with potentially different [=DRM system configuration=] and [=required capability sets=], making it necessary to re-execute the selection process.
Note: If a new period has significantly different requirements in terms of [=DRM system configuration=] or the [=required capability sets=], the media pipeline may need to be re-initialized to play the new period. This may result in a glitch/pause at the period boundary. The specifics are implementation-dependant.
The default [=DRM system configuration=] in the MPD of a live service can change over time. DASH clients are not expected to re-execute DRM workflows if the default [=DRM system configuration=] in the MPD changes for an adaptation set that has already been processed in the past. Such changes will only affect clients that are starting playback.
When encrypted adaptation sets are initially selected for playback or when the selected set of encrypted adaptation sets changes (e.g. because a new period was added to a live service), a DASH client SHOULD execute the following algorithm for [=DRM system=] selection:
-
Let adaptation_sets be the set of encrypted adaptation sets selected for playback.
-
Let signaled_system_ids be the set of DRM system IDs for which a
ContentProtection
descriptor is present in the MPD on any entries in adaptation_sets. -
Let candidate_system_ids be an ordered list initialized with items of signaled_system_ids in any order.
-
Provide candidate_system_ids to [=solution-specific logic and configuration=] for inspection/modification.
- This enables business logic to establish an order of preference where multiple [=DRM systems=] are present.
- This enables business logic to filter out DRM systems known to be unsuitable.
- This enables business logic to include DRM systems not signaled in the MPD.
-
Let default_kids be the set of all distinct
default_KID
values in adaptation_sets. -
Let system_configurations be an empty map of
system ID -> map(default_kid -> configuration)
, representing the [=DRM system configuration=] of eachdefault_KID
for each [=DRM system=]. -
For each system_id in candidate_system_ids:
- Let configurations be a map of
default_kid -> configuration
where the keys are default_kids and the values are the [=DRM system configurations=] initialized with data fromContentProtection
descriptors in the MPD (matching ondefault_KID
and system_id).- If there is no matching
ContentProtection
descriptors in the MPD, the map still contains a partially initialized [=DRM system configuration=] for thedefault_KID
. - Enhance the MPD-provided default [=DRM system configuration=] with synthesized data where appropriate (e.g. [[#CPS-AdditionalConstraints-W3C|to generate W3C Clear Key initialization data in a format supported by the platform API]]).
- If there is no matching
- Provide configurations to [=solution-specific logic and configuration=] for inspection and modification, passing system_id along as contextual information.
- This enables business logic to override the default [=DRM system configuration=] provided by the MPD.
- This enables business logic to inject values that were not embedded in the MPD.
- This enables business logic to reject [=content keys=] that it knows cannot be used, by removing the [=DRM system configuration=] for them.
- Remove any entries from configurations that do not contain all of the following pieces of data:
- License server URL
- [=DRM system=] initialization data in a format accepted by the particular [=DRM system=]; this is generally a
pssh
box [[!CENC]], though some [=DRM systems=] also support other formats
- Add configurations to system_configurations (keyed on system_id).
- Let configurations be a map of
-
Remove from candidate_system_ids any entries for which the map of [=DRM system configurations=] in system_configurations is empty.
-
Let required_capability_sets be a map of
adaptation set -> capability set
, providing the [=required capability set=] of every item in adaptation_sets. -
Match the capabilities of [=DRM systems=] with the [=required capability sets=] of adaptation sets:
- Let supported_adaptation_sets be an empty map of
system ID -> list of adaptation set
, incidating which adaptation sets are supported by which [=DRM systems=]. - For each system_id in candidate_system_ids:
- Let candidate_adaptation_sets by the set of adaptation sets for which system_configurations contains [=DRM system configuration=] (keyed on system_id and then the
default_KID
of the adaptation set).- This excludes from further consideration any adaptation sets that could not be used due to lacking [=DRM system configuration=], even if capabilities match.
- Let maximum_capability_set be the union of all values in required_capability_sets keyed on items of candidate_adaptation_sets.
- Query the [=DRM system=] identified by system_id with the capability set maximum_capability_set, assigning the output to supported_capability_set.
- A [=DRM system=] that is not implemented is treated as having no capabilities.
- For each adaptation_set in candidate_adaptation_sets:
- If supported_capability_set contains all the capabilities in the corresponding entry in required_capability_sets (keyed on adaptation_set), add adaptation_set to the list in supported_adaptation_sets (keyed on system_id).
- Let candidate_adaptation_sets by the set of adaptation sets for which system_configurations contains [=DRM system configuration=] (keyed on system_id and then the
- Let supported_adaptation_sets be an empty map of
-
Remove from supported_adaptation_sets any entries for which the value (the set of adaptation sets) meets any of the following criteria:
- The set is empty (the [=DRM system=] does not support playback of any adaptation set).
- The set does not contain all encrypted media types present in the MPD (e.g. the [=DRM system=] can decrypt only the audio content but not the video content).
-
If supported_adaptation_sets is empty, playback of encrypted content is not possible and the workflow ends.
-
If supported_adaptation_sets contains multiple items, request [=solution-specific logic and configuration=] to select the preferred [=DRM system=] from among them.
- This allows [=solution-specific logic and configuration=] to make an informed choice when different [=DRM systems=] can play different adaptation sets. Contrast this to the initial order of preference that was defined near the start of the algorithm, which does not consider capabilities.
-
If [=solution-specific logic and configuration=] does not make a decision, find the first entry in candidate_system_ids that is among the keys of supported_adaptation_sets. Remove items with any other key from supported_adaptation_sets.
- This falls back to the "order of preference" logic and takes care of scenarios where business logic did not make an explicit choice.
-
Let selected_system_id be the single remaining key in supported_adaptation_sets.
-
Let final_adaptation_sets be the single remaining value in supported_adaptation_sets.
-
Let final_configurations (map of
default_KID -> DRM system configuration
) be the value from system_configurations keyed on selected_system_id. -
Remove from final_configurations any entries keyed on
default_KID
values that are not used by any adaptation set in final_adaptation_sets.- These are the configurations of adaptation sets for which configuration was present but for which the required capabilities were not offered by the [=DRM system=].
-
Prohibit playback of any encrypted adaptation sets that are not in final_adaptation_sets.
- These are existing adaptation sets for which either no [=DRM system configuration=] exists or for which the required capabilities are not provided by the selected [=DRM system=].
-
Execute the [[#CPS-activation-workflow|DRM system activation workflow]], providing selected_system_id and final_configurations as inputs.
If a [=DRM system=] is successfully selected, activation and potentially one or more license requests will follow before playback can proceed. These related workflows are described in the next chapters.
Once a suitable [=DRM system=] has been selected, it must be activated by providing it a list of [=content keys=] that the DASH client requests to be made available for content decryption, together [=DRM system=] specific initialization data for each of the [=content keys=]. The result of activation is a [=DRM system=] that is ready to decrypt zero or more encrypted adaptation sets selected for playback.
During activation, it may be necessary [[#CPS-license-request-workflow|to perform license requests]] in order to obtain some or all of the [=content keys=] and the usage policy that constrains their use. Some of the requested [=content keys=] may already be available to the [=DRM system=], in which case no license request will be triggered.
Note: The details of stored [=content key=] management and persistent DRM session management are out of scope of this document - workflows described here simply accept the fact that some [=content keys=] may already be available, regardless of why that is the case or what operations are required to establish [=content key=] persistence.
Once a suitable [=DRM system=] [[#CPS-selection-workflow|has been selected]], a DASH client SHOULD execute the following algorithm to activate it:
- Let configurations be the input to the algorithm; it is a map with the entry keys being
default_KID
values identifying the [=content keys=] and the entry values being the [=DRM system configuration=] to use with that particular [=content key=]. - Let pending_license_requests be an empty set.
- For each kid and config pair in configurations invoke the platform API to activate the selected [=DRM system=] and signal it to make kid available for decryption, passing the [=DRM system=] the initialization data stored in config.
- If the [=DRM system=] indicates that one or more license requests are needed, add any license request data provided by the [=DRM system=] and/or platform API to pending_license_requests, together with the associated kid and config values.
- If pending_license_requests is not an empty set, execute the [[#CPS-license-request-workflow|license request workflow]] and provide this set as input to the algorithm.
- Inspect the set of [=content keys=] the [=DRM system=] indicates are now available and deselect from playback any adaptation sets for which the [=content key=] has not become available.
- Inspect the set of remaining adaptation sets to determine if a sufficient data set remains for successful playback. Raise error if playback cannot continue.
The default format for initialization data supplied to a [=DRM system=] is a pssh
box. However, if the DASH client has knowledge of any special initialization requirements of a particular [=DRM system=], it MAY supply initialization data in other formats (e.g. the keyids
JSON structure used by W3C Clear Key). Presence of initialization data in the expected format is considered during [[#CPS-selection-workflow|DRM system selection]] when determining whether a [=DRM system=] is a valid candidate.
For historical reasons, platform APIs often implement [=DRM system=] activation as a per-content-key operation. Some APIs and [=DRM system=] implementations may also support batching all the [=content keys=] into a single activation operation, for example by combining multiple "[=content key=] and DRM system configuration" data sets into a single data set in a single API call. DASH clients MAY make use of such batching where supported by the platform API. The workflow in this chapter describes the most basic scenario where activation must be performed separately for each [=content key=].
Note: The batching may, for example, be accomplished by concatenating all the pssh
boxes for the different [=content keys=]. Support for this type of batching among DRM systems and platform APIs remains uncommon, despite the potential efficiency gains from reducing the number of license requests triggered.
It is possible that not all of the encrypted adaptation sets selected for playback can actually be played back (e.g. because a [=content key=] for ultra-HD content is only authorized for use by implementations with a high [=robustness level=]). The unavailability of one or more [=content keys=] SHOULD NOT be considered a fatal error condition as long as at least one audio and at least one video adaptation set remains available for playback (assuming both content types are initially selected for playback). This logic MAY be overridden by solution specific business logic to better reflect end-user expectations.
A DASH client can request a [=DRM system=] to enable decryption using any set of [=content keys=] (if it has the necessary [=DRM system configuration=]). However, this is only a request and playback can be countermanded at multiple stages of processing by different involved entities.
The set of [=content keys=] made available for use can be far smaller than the set requested by a DASH client. Example workflow indicating potential instances of [=content keys=] being removed from scope.The set of available [=content keys=] is only known at the end of executing the activation workflow and may decrease over time (e.g. due to [=license=] expiration). The proper handling of unavailable keys depends on the limitations imposed by the platform APIs.
Advisement: [=Media platform=] APIs often refuse to start or continue playback if the [=DRM system=] is not able to decrypt all the data already in [=media platform=] buffers.
It may be appropriate for a DASH client to avoid buffering data for encrypted adaptation sets until the required [=content key=] is known to be available. This allows the client to avoid potentially expensive buffer resets and rebuffering if unusable data needs to be removed from buffers.
Note: The DASH client should still download the data into intermediate buffers for faster startup and simply defer submitting it to the [=media platform=] API until key availability is confirmed.
The set of available [=content keys=] can change over time (e.g. due to [=license=] expiration or due to new periods in the presentation requiring different content keys).
If a [=content key=] expires during playback it is common for a [=media platform=] to pause playback until the [=content key=] can be refreshed with a new [=license=] or until data encrypted with the now-unusable [=content key=] is removed from buffers. DASH clients SHOULD acquire new [=licenses=] in advance of [=license=] expiration and SHOULD implement appropriate recovery/fallback behavior to ensure a minimally disrupted user experience in situations where some [=content keys=] remain available even after attempted license renewal.
A DASH client SHALL monitor the set of default_KID
values that are required for playback and either request the [=DRM system=] to make these [=content keys=] available or deselect the affected adaptation sets when the [=content keys=] become unavailable. Conceptually, any such change can be handled by re-executing the [[#CPS-selection-workflow|DRM system selection]] and [[#CPS-activation-workflow|activation workflows]], although platform APIs may also offer more fine-grained update capabilities.
Note: Some CDM implementations emit license renewal signals using the EME license-renewal
[[!encrypted-media]] message. CDMs are not obligated to implement this mechanism and DASH clients cannot rely on this message as the only source of expiration information. In particular, the MediaKeySession.expiration
property needs to be monitored to stay informed of upcoming license expiration.
A DASH client MAY enable [=solution-specific logic and configuration=] to disable proactive license acquisition, for example to enable scenarios where [=solution-specific logic and configuration=] explicitly triggers license requests at desired times and with desired parameters.
When [=content keys=] are acquired, the [=license=] that delivers them also supplies a policy for the [=DRM system=], instructing it how to protect the content that is made accessible by the [=content keys=].
Protection policy may define the following example requirements:
- All connected displays must support HDCP 2.2 or newer.
- The video display area must be no more than 1280x720 pixels.
- Minimum [=DRM system=] [=robustness level=] is "800".
Typical [=DRM systems=] will enforce the most restrictive protection policy from among all active [=content keys=] and will refuse to start playback if any of the constraints cannot be satisfied! As a result, it can be the case that even though only the constraints for a UHD video stream cannot be satisfied, playback of even the lower quality levels is blocked.
In many cases, it might be more desirable to instead exclude the UHD quality level from the set of adaptation sets selected for playback and [=DRM system=] activation. Alternatively, there may be a different [=DRM system=] implementation available on the device that is capable of satisfying the constraints. It is not possible for a DASH client to resolve these constraints as it has no knowledge of what policy applies nor of the capabilities of the different [=DRM system=] implementations.
[=Solution-specific logic and configuration=] SHOULD be used to select the most suitable [=DRM system=], taking into consideration the protection policy, and to preemptively exclude adaptation sets from playback if it can be foreseen that the protection policy for their [=content keys=] cannot be satisfied. Likewise, license servers SHOULD NOT provide [=content keys=] if it can be foreseen that the recipient will be unable to satisfy their protection policy.
DASH clients performing license requests SHOULD follow the [[#CPS-lr-model|DASH-IF interoperable license request model]]. The remainder of this chapter only applies to DASH clients that follow this model. Alternative implementations are possible and in common use but are not interoperable and are not described in this document.
[=DRM systems=] generally do not perform license requests on their own. Rather, when they determine that a [=license=] is required, they generate a document that serves as the license request body and expect the DASH client to deliver it to a license server for processing. The latter returns a suitable response that, if a [=license=] is granted, encapsulates the [=content keys=] in an encrypted form only readable to the DRM system.
Simplified conceptual model of license request processing. Many details omitted.The request and response body are in [=DRM system=] specific formats and considered opaque to the DASH client. A DASH client SHALL NOT modify the request body or the response body.
The license request workflow defined here exists to enable the following goals to be achieved without the need to customize the DASH client with logic specific to a [=DRM system=] or license server implementation:
- Provide proof of authorization if the license server requires the DASH client to prove that the user being served has the rights to use the requested [=content keys=].
- Execute the license request workflow driven purely by the MPD, without any need for [=solution-specific logic and configuration=].
- Detect common error scenarios and present an understandable message to the user.
The proof of authorization is optional and the need to attach it to a license request is indicated by the presence of at least one dashif:authzurl
in the [=DRM system configuration=]. The proof of authorization is a [[!jwt|JSON Web Token]] in compact encoding (the aaa.bbb.ccc
form) returned as the HTTP response body when the DASH client performs a GET request to this URL. The token is attached to a license request in the HTTP Authorization
header with the Bearer
type. For details, see [[#CPS-lr-model]].
Error responses from both the authorization service and the license server SHOULD be returned as [[rfc7807 obsolete]] compatible responses with a 4xx or 5xx status code and Content-Type: application/problem+json
.
DASH clients SHOULD implement retry behavior to recover from transient failures and expiration of [=authorization tokens=].
To process license requests queued during execution of the [[#CPS-activation-workflow|DRM system activation workflow]], the client SHOULD execute the following algorithm:
- Let pending_license_requests be the set of license requests that the [=DRM system=] has requested to be performed, with at least the following data present in each entry:
- The license request body provided by the [=DRM system=].
- The [=DRM system configuration=].
- Let retry_requests be an empty set. It will contain the set of license requests that are to be retried due to transient failure.
- Let pending_authz_requests be a map of
URL -> GUID[]
, with the keys being authorization service URLs and the values being lists ofdefault_KIDs
. The map is initially empty. - For each request in pending_license_requests:
- If the [=DRM system configuration=] does not contain at least one value for
dashif:authzurl
, skip to the next loop iteration. This means that no [=authorization token=] is to be attached to this license request. - Create/update the entry in pending_authz_requests with the key being the set of
dashif:authzurl
values; add thedefault_KID
to the list in the map entry value.
- If the [=DRM system configuration=] does not contain at least one value for
- Let authz_tokens be a map of
GUID -> string
, with the keys beingdefault_KIDs
and the values being the associated [=authorization tokens=]. The map is initially empty. - For each authz_url_set and kids pair in pending_authz_requests:
- If the DASH client has a cached [=authorization token=] previously acquired for the same authz_url_set and kids combination that still remains valid according to its
exp
"Expiration Time" claim:- Let authz_token be the cached [=authorization token=].
- Else:
- Create a comma-separated list from kids in ascending alphanumeric (ASCII) order.
- Let authz_url be a random item from authz_url_set.
- Let authz_url_with_kids be authz_url with an additional query string parameter named
kids
with the value from kids.- authz_url may already include query string parameters, which should be preserved!
- Perform an HTTP GET request to authz_url_with_kids (following redirects).
- Include any relevant HTTP cookies.
- Allow [=solution-specific logic and configuration=] to intercept the request and inspect/modify it as needed (e.g. provide additional HTTP request headers to enable user identification).
- If the response status code [[#CPS-lr-model-errors|indicates failure]], make a note of any error information for later processing and skip to the next authz_url.
- Let authz_token be the HTTP response body.
- Submit authz_token into the DASH client cache, with the cache key being a combination of authz_url_set and kids, and the cache entry expiration being defined by the
exp
"Expiration Time" claim in the [=authorization token=] (defaulting to never expires).
- For each kid in kids, add an entry to authz_tokens with the key kid and the value being authz_token.
- If the DASH client has a cached [=authorization token=] previously acquired for the same authz_url_set and kids combination that still remains valid according to its
- For each request in pending_license_requests:
- If the [=DRM system configuration=] from request contains an authorization service URL but there is no entry in authz_tokens keyed on the
default_KID
from request, skip to the next loop iteration.- This occurs when an [=authorization token=] is required but cannot be obtained for this license request.
- Execute an HTTP POST request with the following parameters:
- Request body is the license request body from request.
- Request URL is defined by [=DRM system configuration=]. If multiple license server URLs are defined, select a random URL from the set.
- If authz_tokens contains an entry with the key being the
default_KID
from request, add theAuthorization
header with the value being the stringBearer
concatenated with a space and the [=authorization token=] from authz_tokens (e.g.Bearer aaa.bbb.ccc
).
- If the response status code [[#CPS-lr-model-errors|indicates failure]]:
- Expel the used [=authorization token=] (if any) from the DASH client cache to force a new token to be used for any future license requests.
- If the DASH client believes that retrying the license request might succeed (e.g. because the response indicates that the error might be transient or due to an expired [=authorization token=] that can be renewed), add request to retry_requests.
- Make a note of any error information for later processing and presentation to the user.
- Skip to the next loop iteration.
- Submit the HTTP response body to the [=DRM system=] for processing.
- This may cause the [=DRM system=] to trigger additional license requests. Append any triggered request to pending_license_requests and copy the [=DRM system configuration=] from the current entry, processing the additional entry in a future iteration of the same loop.
- If the [=DRM system=] indicates a failure to process the data, make a note of any error information for later processing and skip to the next loop iteration.
- If the [=DRM system configuration=] from request contains an authorization service URL but there is no entry in authz_tokens keyed on the
- If retry_requests is not empty, re-execute this workflow with retry_requests as the input.
While the above algorithm is presented sequentially, authorization requests and license requests may be performed in a parallelized manner to minimize processing time.
At the end of this algorithm, all pending license requests have been performed. However, it is not necessary that all license requests or authorization requests succeed! For example, even if one of the requests needed to obtain an HD quality level [=content key=] fails, other requests may still make SD quality level [=content keys=] available, leading to a successful playback if the HD quality level is deselected by the DASH client. Individual failing requests therefore do not indicate a fatal error. Rather, such error information should be collected and provided to the top-level error handler of the DRM system activation workflow, which can make use of this data to present user-friendly messages if it decides that meaningful playback cannot take place with the final set of available [=content keys=]. See also [[#CPS-unavailable-keys]].
In some situations a DASH client can foresee the need to make new [=content keys=] available for use or to renew the [=licenses=] that enable [=content keys=] to be used. For example:
- Live DASH services can at any time introduce new periods that use different [=content keys=]. They can also alternmate between encrypted and clear content in different periods.
- The [=license=] that enables a [=content key=] to be used can have an expiration time, after which a new [=license=] is required.
DASH clients SHOULD perform license acquisition ahead of time, activating a [=DRM system=] before it is needed or renewing [=licenses=] before they expire. This provides the following benefits:
- Playback can continue seamlessly when [=licenses=] are renewed, without pausing for license acquisition.
- New [=content keys=] are already available when content needs them, again avoiding a pause for license acquisition.
To avoid a huge number of concurrent license requests causing license server overload, a DASH client SHOULD perform a license request at a randomly selected time between the moment when it became aware of the need for the license request and the time when the [=license=] must be provided to a [=DRM system=] (minus some safety margin).
Multiple license requests to the same license server with the same [=authorization token=] SHOULD be batched into a single request if the [=media platform=] API supports this. See [[#CPS-activation-workflow]] for details.
The possibility for ahead-of-time [=DRM system=] activation, seamless [=license=] renewal and license request batching depends on the specific [=DRM system=] and [=media platform=] implementations. Some implementations might not support optimal behavior.