DRM API¶
Auto-generated reference for the DRM systems: Widevine, PlayReady, ClearKey, and related helpers. For configuring DRM as a user, see DRM & CDM Setup.
ClearKey
¶
AES-128 ClearKey (HLS) DRM system.
Give the IV where possible. If you do not give an IV, unshackle sets it to of the same bit-size as the content key.
warn_clear
¶
Warn once per track that unshackle passed a segment through undecrypted.
from_m3u_key
classmethod
¶
Load a ClearKey from an M3U(8) Playlist's EXT-X-KEY.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
m3u_key
|
Key
|
A |
required |
session
|
Optional[Session]
|
Optional HTTP session used to request external URIs with. Useful to set headers, proxies, cookies, and so forth. |
None
|
ClearKeyCENC
¶
W3C EME ClearKey (org.w3.clearkey) DRM System over MPEG-CENC tracks.
Distinct from the HLS AES-128 ClearKey class: a license server gives the keys
here as a JWK Set keyed by KID, and the media is standard CENC
(decrypted with shaka-packager/mp4decrypt KID:KEY pairs, same as Widevine).
Exceptions
¶
to_dict
¶
Serialise this DRM instance for export/import (KIDs + license URL).
unshackle stores the content keys once at the export's track level, and does not duplicate them here.
get_license_challenge
¶
Assemble the W3C EME ClearKey JSON license request for the unkeyed KIDs.
get_content_keys
¶
Get Content Keys for this DRM Instance from a ClearKey license server.
The licence param is a function. unshackle gives it the W3C JSON license
request as challenge. It may return the JWK Set license as a dict, JSON str,
or bytes. If it returns None and the manifest gave a Laurl, unshackle POSTs the
challenge there directly instead.
decrypt
¶
Decrypt a Track with ClearKey DRM (standard CENC). Args: path: Path to the encrypted file to decrypt Raises: EnvironmentError if the required decryption executable could not be found. ValueError if unshackle has not yet downloaded the track. SubprocessError if the decryption process returned a non-zero exit code.
mp4decrypt_key_args
¶
Build the mp4decrypt --key arguments for every content key.
MonaLisa
¶
MonaLisa DRM System.
Unlike Widevine/PlayReady, MonaLisa does not use a challenge/response flow with a license server. Instead, the service API gives the PSSH value (ticket) directly, and a WASM module extracts the content keys locally.
Initialise MonaLisa DRM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ticket
|
Union[str, bytes]
|
PSSH value from service API (base64 string or raw bytes). |
required |
device_path
|
Path
|
Path to the CDM device file (.mld). |
required |
tool_path
|
Optional[Path]
|
Optional path to an external decryption binary. |
None
|
**kwargs
|
Any
|
Additional metadata stored in self.data. |
{}
|
Raises:
| Type | Description |
|---|---|
TicketNotFound
|
If ticket/PSSH is empty. |
KeyExtractionFailed
|
If content key extraction fails. |
pssh
property
¶
Get the raw PSSH/ticket value as a string.
Returns:
| Type | Description |
|---|---|
str
|
The raw PSSH value as a base64 string. |
content_id
property
¶
Extract the Content ID from the PSSH for display.
The PSSH contains an embedded Content ID at bytes 21-75 with format: H5DCID-V3-P1-YYYYMMDD-HHMMSS-MEDIAID-TIMESTAMP-SUFFIX
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The Content ID string if extractable, None otherwise. |
content_keys
property
¶
Get content keys in the same format as Widevine/PlayReady.
Returns:
| Type | Description |
|---|---|
dict[UUID, str]
|
Dictionary mapping KID to the content key hex string. |
Exceptions
¶
from_ticket
classmethod
¶
Make a MonaLisa DRM instance from a PSSH/ticket.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ticket
|
Union[str, bytes]
|
PSSH value from service API. |
required |
device_path
|
Path
|
Path to the CDM device file (.mld). |
required |
tool_path
|
Optional[Path]
|
Optional path to an external decryption binary. |
None
|
Returns:
| Type | Description |
|---|---|
MonaLisa
|
MonaLisa DRM instance with extracted keys. |
decrypt_segment
¶
Decrypt an individual segment file using the configured CLI tool via subprocess.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segment_path
|
Path
|
Path to the segment file to decrypt. |
required |
output_path
|
Optional[Path]
|
Optional path for the decrypted output segment. |
None
|
decrypt
¶
Decrypt a media file (segment or track) using the configured CLI tool via subprocess.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the target file to decrypt. |
required |
output_path
|
Optional[Path]
|
Optional path for the decrypted output file. |
None
|
is_segment
|
bool
|
Set True if this is an individual segment rather than a full track. |
False
|
PlayReady
¶
PlayReady DRM System.
extract_kids_from_pssh_b64
¶
Extract all KIDs from base64-encoded PSSH data.
to_dict
¶
Serialise this DRM instance for export/import (PSSH + KIDs).
unshackle stores the content keys once at the export's track level, and does not duplicate them here.
header_kids
staticmethod
¶
Return the KIDs one WRM header names, in header order.
absorb
¶
Fold sibling PlayReady objects into this one so their headers and KIDs get licensed too.
A manifest can attach one PlayReady object per WRM header to the same track (ISM shares its Protection list across tracks; HLS emits one per EXT-X-KEY). The caller keeps this object's identity, which the decrypt path and drm_lock depend on.
distinct_headers
¶
Return the WRM headers to license, deduplicated by the KID set each one names.
Two headers naming the same KIDs (a v4.0 header beside its v4.3 twin, or one PRH per rendition for one content key) cost one challenge. A header with no readable KID is kept: it may still be the only route to a content key nothing else names.
pro_b64_for
staticmethod
¶
Build a base64 one-record PlayReady Object holding only this header.
Remote CDMs send the value given to set_pssh_b64 rather than the header passed to get_license_challenge, so a per-header challenge needs a per-header PRO.
extract_keys_from_cdm
¶
Extract keys from CDM session with cross-library compatibility.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cdm
|
Cdm
|
CDM instance |
required |
session_id
|
bytes
|
Session identifier |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary mapping KID UUIDs to hex keys |
get_content_keys
¶
License every distinct WRM header whose KIDs still lack a content key.
A v4.2+ header may list several KIDs and one response may stack several licences, so one challenge often covers everything. Content that ships several headers (ISM with one ProtectionHeader per track type, HLS with one PRH per playlist) gets one challenge per header that is not yet covered. Headers are sent as-is: Microsoft lets the server ignore the header, so a merged header could ask for keys it never grants.
A header that a round refused, or that yielded nothing, is not sent again by this object: every track of a title runs this method, and a repeat would only repeat the refusal.
detect_revocation
staticmethod
¶
Return the decoded error string if a revocation HRESULT is present, else None.
Reads the code from the raw SOAP body (
decrypt
¶
Decrypt a Track with PlayReady DRM. Args: path: Path to the encrypted file to decrypt Raises: EnvironmentError if the required decryption executable could not be found. ValueError if unshackle has not yet downloaded the track. SubprocessError if the decryption process returned a non-zero exit code.
own_kids
¶
Return the KIDs that identify this track's own content key.
The KID given to the constructor (from the manifest or the init segment) names the track exactly. A PSSH can name the KIDs of other renditions too.
mp4decrypt_key_args
¶
Build the mp4decrypt --key arguments for every content key and the zero-KID fallback.
decrypt_with_shaka_packager
¶
Decrypt with shaka-packager (original method)
Widevine
¶
Widevine DRM System.
Exceptions
¶
PSSHNotFound
¶
Bases: Exception
PSSH (Protection System Specific Header) was not found.
KIDNotFound
¶
Bases: Exception
KID (Encryption Key ID) was not found.
CEKNotFound
¶
Bases: Exception
CEK (Content Encryption Key) for KID was not found in License.
EmptyLicense
¶
Bases: Exception
License returned no Content Encryption Keys.
from_track
classmethod
¶
Get PSSH and KID from within the Initiation Segment of the Track Data. It also tries to get PSSH and KID from other track data like M3U8 data as well as through FFprobe.
Make a Widevine DRM System object from a track's information. Use this method only when a PSSH cannot be given directly. It is rare to need to use this.
You can give your own requests.Session to use custom headers
and more.
Raises:
| Type | Description |
|---|---|
PSSHNotFound
|
If the PSSH was not found within the data. |
KIDNotFound
|
If the KID was not found within the data or PSSH. |
from_init_data
classmethod
¶
Get PSSH and KID from within Initialization Segment Data.
Use this method only when a PSSH cannot be given directly. It is rare to need to use this.
Raises:
| Type | Description |
|---|---|
PSSHNotFound
|
If the PSSH was not found within the data. |
KIDNotFound
|
If the KID was not found within the data or PSSH. |
to_dict
¶
Serialise this DRM instance for export/import (PSSH + KIDs).
unshackle stores the content keys once at the export's track level, and does not duplicate them here.
get_content_keys
¶
Make a CDM Session and get Content Keys for this DRM Instance. The certificate and license params are functions. unshackle gives them the challenge and the session ID.
decrypt
¶
Decrypt a Track with Widevine DRM. Args: path: Path to the encrypted file to decrypt Raises: EnvironmentError if the required decryption executable could not be found. ValueError if unshackle has not yet downloaded the track. SubprocessError if the decryption process returned a non-zero exit code.
own_kids
¶
Return the KIDs that identify this track's own content key.
The KID given to the constructor (from the manifest or the init segment) names the track exactly. A PSSH can name the KIDs of other renditions too.
mp4decrypt_key_args
¶
Build the mp4decrypt --key arguments for every content key and the zero-KID fallback.
decrypt_with_shaka_packager
¶
Decrypt with shaka-packager (original method)
drm_from_dict
¶
Reconstruct a Widevine/PlayReady/ClearKeyCENC DRM instance from its to_dict() form.
Rebuilds the PSSH from the stored base64 (KIDs for ClearKey, which has no PSSH) and re-injects any saved content keys so the resulting object can decrypt without contacting a license server.
real_kids
¶
Return the KIDs a DRM object names, without the all-zero and test-pattern placeholders.
own_kids
¶
Return the real KIDs that identify the track's own content key, as the DRM object knows them.