Playing protected content with Nagra DRM - Android
Digital Rights Management (DRM) solutions often require specific data exchanges with a license server, usually in proprietary formats. Rather than integrating multiple license providers directly into the core of our player, we leverage flexible configuration options through the player configuration. This guide explains how to integrate the Bitmovin Android Player SDK with Nagra Secure Services Platform (SSP) for Widevine DRM license acquisition and secure session management.
Pre-requisites
Before you begin, please ensure you have access to Nagra Documentation, Nagra SSP backend for fetching required tokens and also access to Bitmovin player key to use Bitmovin player. Please refer to links below for respective documentation.
- Secure Session Management Documentation
- Session Session Manager
- BITMOVIN_PLAYER_KEY : You can get in touch with your Nagra or Bitmovin contact for this. You can also sign up for a trial account.
Configuration
1. Application preparation for DRM content playback and Secure Session Management
Note:
The steps below describe interactions between your application and Nagra’s backend.
These are outside the scope of Bitmovin’s integration but are included here because they are required to obtain certain authorization tokens needed to successfully request DRM licenses from the Nagra backend.
Please refer to Nagra’s documentation portal or contact your Nagra representatives for detailed information about these application-to-backend interactions.
- Authorization
Your application signs in to Nagra's backend. Upon successful sign-on, you obtain a login token. - Content Token Retrieval
Your application requests aCONTENT_TOKEN
from the Nagra backend. - Secure Session Setup
Your application initiates a secure session with the Nagra SSP backend by sending theCONTENT_TOKEN
toNAGRA_SSM_SETUP_URL
. Upon successful setup, you receive anSSM_TOKEN
. - Secure Session Teardown
Once playback finishes or you switch to another piece of content, your application terminates the secure session by callingNAGRA_SSM_TEARDOWN_URL
. If you plan to play a different piece of DRM-protected content, you must first repeat the Content Token Retrieval and Secure Session Setup steps to obtain a new content token andSSM_TOKEN
.
2. Bitmovin Player Configuration for Widevine Playback
This section covers how to configure the Bitmovin Player for playback of Nagra protected Widevine DRM content, we will do two things here.
- Add a NetworkConfig.preprocessHttpRequest callback to inject CONTENT_TOKEN and SSM_TOKEN into the license and certificate requests.
- Use SourceConfig and WidevineConfig to specify license server URLs and custom prepareMessage / prepareLicense callbacks for request/response formatting.
2.1 Configure NetworkConfig.preprocessHttpRequest (code snippet below)
The preprocessHttpRequest callback allows you to modify DRM-related requests before the Bitmovin Player sends them out.
- Add the CONTENT_TOKEN and SSM_TOKEN as custom HTTP header("nv-authorizations") in the Widevine DRM request.
- Then set HTTP headers in Widevine request depending on type of the request.
- Update NAGRA_LICENSE_RENEWAL_SERVER_URL as the request URL for Widevine renewal requests.
val contentToken: String = TODO("fetch content token")
val ssmToken: String = TODO("fetch ssm token")
val sourceConfig = SourceConfig(
url = TODO("CONTENT_MANIFEST_URL"),
type = SourceType.Dash,
title = "Nagra Connect Protected Source",
drmConfig = NagraConnectConfig.Builder()
.build(
licenseUrl = TODO("NAGRA_CONNECT_LICENSE_URL"),
operatorVault = TODO("NAGRA_OPERATOR_VAULT"),
).apply {
httpHeaders = mutableMapOf(
"nv-authorizations" to "$contentToken,$ssmToken",
"x-nagra-property" to "nagraOpVault",
"Content-Type" to "application/json",
"Accept" to "application/json",
)
},
)
player.load(sourceConfig)
2.2 Configure SourceConfig including Widevine DRM Config (code snippet below)
Next we need to specify the Widevine license server URL via LA_URL and implement the prepareMessage and prepareLicense callbacks, which handle request/response formatting for Nagra’s Widevine request/response.
- Add either the DASH/HLS Manifest as the content URL.
- Add NAGRA_WIDEVINE_LICENSE_SERVER_URL as license_url in WidevineConfig constructor.
- Add prepareMessage configuration to format the Widevine license request message as expected by Nagra Widevine server.
- Add prepareLicense configuration to re-format the Widevine license response coming from Nagra Widevine server into format required by Bitmovin player.
val contentToken: String = TODO("fetch content token")
val ssmToken: String = TODO("fetch ssm token")
val sourceConfig = SourceConfig(
url = TODO("CONTENT_MANIFEST_URL"),
type = SourceType.Dash,
title = "Nagra Connect Protected Source",
drmConfig = NagraConnectConfig.Builder()
.build(
licenseUrl = TODO("NAGRA_CONNECT_LICENSE_URL"),
operatorVault = TODO("NAGRA_OPERATOR_VAULT"),
).apply {
httpHeaders = mutableMapOf(
"nv-authorizations" to "$contentToken,$ssmToken",
"x-nagra-property" to "nagraOpVault",
"Content-Type" to "application/json",
"Accept" to "application/json",
)
},
)
player.load(sourceConfig)
Playback Sequence
- The application prepares its configuration and required tokens, then loads the source into the Bitmovin Player using the load() API.
- The Bitmovin Player downloads the playlist and segments, identifying that the content is protected with Widevine.
- The Bitmovin Player initiates the Widevine license acquisition process, which proceeds as follows:
- License Request: The Widevine formware in the device creates a Widevine challenge/request. The WidevineConfig.prepareMessage callback reformats this request into a JSON-encoded, base64 string as required by the Nagra DRM server.
- Request Preprocessing: The Bitmovin Player invokes the NetworkConfig.preprocessHttpRequest callback registered by the application. If this callback is triggered before playback starts, it indicates an initial license request. Here, the application sets the necessary HTTP headers in the request.
- Response Handling: The Bitmovin Player sends the request to the Nagra DRM server and receives a response. The WidevineConfig.prepareLicense callback reformats this response into a format compatible with the Bitmovin Player. The response also includes an updated SSM_TOKEN, which is saved for use in subsequent license renewal requests.
- Playback Start: After the initial license acquisition succeeds, playback of the content begins.
- Failure Handling: If license acquisition fails, the player throws a fatal error with a detailed message.
- Once playback begins successfully, DRM license renewal occurs periodically at set intervals. The renewal sequence is as follows:
- The Widevine CDM in the browser detects the need for a license renewal and initiates a renewal request.
- The license renewal request follows the same process as the initial request, with two main differences:
- The SSP endpoint for the renewal request is different from the initial license request, so the NetworkConfig.preprocessHttpRequest callback updates the HTTP request URL accordingly.
- An updated SSM token is returned by the Nagra DRM server in the initial license response’s HTTP header, which the application must store and include in subsequent renewal requests.
- When playback ends or the user switches to new content, the application should tear down the existing SSM session. Terminating the SSM session is handled directly with the Nagra SSP backend (outside the Bitmovin Player). This step is crucial because failing to tear down previous sessions may cause the Nagra SSP backend to deny new session requests, preventing further playback.
note:
The licence renewal interval is determined by Nagra. Please consult Nagra documentation or your Nagra contact for more details on this.
And that's it. If you have any issues implementing this please reach out to your Bitmovin and Nagra representatives.
For similar examples across other platforms also using Nagra security please see the links below:
Playing protected content with Nagra DRM - ios
Updated about 24 hours ago