DASH stream playback with NAGRA CONNECT
To test this feature and view the connect-dash example code, please see the Android SDK 5 Example Code Quick Start guide.
Like other protected content, the CONNECT Player makes use of an OTVCommonMediaDrmCallback
-derived class - OTVConnectMediaDrmCallback
. Unlike HLS+CONNECT, there is no use of the OTVConnectManager
class; the implementation is more like DASH+Widevine.
The CONNECT Player supports the CENC encryption sampling method (including support for multiple encrypted sub-samples); pattern encryption is not supported. Support for CBCS/CMAF with CONNECT PRM is not guaranteed and depends on the underlying SoC.
PRM signalization can be provided as either a<cenc:pssh
>
tag or <prm:PRMSignalization>
tag inside the <ContentProtection>
tag (in the stream's manifest .mpd), or inside the header of the downloaded segment. Signalization data in the manifest will override data in the segment.
Enabling playback of CONNECT-encrypted DASH streams comprises the following steps:
- Initialisation and configuration of the callback class for working with the CONNECT-enabled licence server, including setting the Operator Vault.
- Configuration of the callback object with stream-specific parameters.
- Setting player view with callback object and stream path.
Unlike CONNECT+HLS, there is no need for the OTVConnectManager
, and there are no specific actions for provisioning.
OTVConnectMediaDrmCallback
The SDK provides the OTVConnectMediaDrmCallback
as the default implementation of the OTVMediaDrmCallback
interface, which handles communication with the provisioning and licence servers and is used in the example code. This is the same class used for CONNECT+HLS.
Rather than directly implementing the OTVMediaDrmCallback
interface, OTVConnectMediaDrmCallback
implements the abstract OTVCommonMediaDrmCallback
class, which has a single constructor with the parameter defaultLicenseUrl
.
Some licence servers expect extra information from the application. This information is a blob of data in a specific data field within the key request challenge data from the MediaDRM plug-in and is sent to the licence server. The MediaDRM plug-in library can be configured to add that extra data by setting an option in the OTVConnectMediaDrmCallback
class instance. For example, configuring the clientData
and/or protectedClientData
fields with application data adds this data to key requests' challenge data as third-party applicationClearData
and applicationProtectedData
data fields respectively.
For more information, please refer to your licence server documentation.
Initialisation and configuration
The OTVConnectMediaDrmCallback
is similar to callback classes provided in the CONNECT Player SDK; please note:
- Configuration of the
OTVConnectMediaDrmCallback
requires one additional step - setting up the Operator Vault data.
This is done by reading theopvault.json
file as a binary stream and passing the byte array as a"nagraOpVault"
DRM propertyconnectDrmCallback.setDrmPropertyByteArray("nagraOpVault", opVault);
- Provisioning is only required once and will take place (if not previously provisioned) when the Android system's
executeProvisionRequest()
is called.
Provisioning
The OTVConnectMediaDrmCallback
class, provided in the SDK has built-in handling of provisioning requests by implementing:
@Override
public byte[] executeProvisionRequest(UUID uuid, ExoMediaDrm.ProvisionRequest request) throws MediaDrmCallbackException
Licence request
The OTVConnectMediaDrmCallback
class, provided in the SDK has built-in handling of license requests by implementing:
@Override
public byte[] executeKeyRequest(UUID uuid, ExoMediaDrm.KeyRequest request) throws MediaDrmCallbackException
Setting stream-specific playback parameters
Stream-specific parameters typically comprise stream tokens (configured in the callback) and other parameters set in the callback's setKeyRequestProperty()
, setKeyRequestOption()
and setDrmPropertyByteArray()
.
Setting player view with callback object and stream path
Once all parameters are configured in the callback, the callback reference is passed to the player (OTVVideoView
) instance using OTVVVideoView.setMediaDrmCallback()
and the stream's path can be set to begin playback.
Multi-session mode
The callback must be configured to multi-session mode when more than one key is required to play a stream, such as:
- Key-per-track - for example, when video and audio are encrypted with different keys or when the HD adaptation set requires a different key from the SD adaptation set.
- Key-rotation - where keys change over time
- Temporal pre-delivery - when multiple keys are delivered ahead of key rotation to save key requests.
Internally, the player starts a DRM session whenever a key is required. If more than one key is required in a single-session mode, playback will stop.
By default, multi-session mode is enabled. To set the callback for multi-session mode, the following should be called (before starting playback):
callback.setMultiSession(true);
Licence pre-delivery/pre-fetching
Licence pre-fetching is when the application gets the licence from the licence server ahead of playback so that when playback is required, no licence requests are sent from the callback object.
Licence pre-delivery, also called pre-fetching, is not the same as Temporal key pre-delivery, which is an attribute of Key Rotation streams. Multi-session mode is not required for pre-fetching,
The connect-dash example code shows how OTVConnectMediaDrmCallback
is instantiated and configured with an OpVault and DRM request properties. This is built on this to handle pre-fetching of a licence. A one-time or fixed content token needs to be provided for normal playback (where the licence is fetched during playback). To pre-fetch the licence, the request needs to be sent with a device token that permits pre-fetching:
callback.setKeyRequestProperty("nv-authorizations", "--device_token--");
The token should contain the device id:
{
"ver": "1.0",
"typ": "DevAuthN",
"deviceId": "Device_ID2"
}
The device id is required when generating the device token. for example prm.NAGRA/C220/FAS.Android-DeviceId-01
.
Pre-delivery callbacks for success and failure (implementing the OTVConnectLicensePreDeliveryListener
interface) now needs to be created:
OTVConnectLicensePreDeliveryListener connectPreDeliveryListener = new OTVConnectLicensePreDeliveryListener() {
@Override
public void onSuccess(int numLicense) {
String message = "number of license of pre-delivery :" + numLicense;
Log.i(TAG,message);
mActivity.runOnUiThread(() -> {
Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show();
});
}
@Override
public void onFailure(int what, int extra) {
String message = ErrorCodeTranslator.translate(what,extra);
Log.i(TAG, message);
mActivity.runOnUiThread(() -> {
Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show();
});
}
};
An OTVConnectLicensePreDelivery
class supporting pre-delivery of CONNECT licences is instantiated using the DRM callback and the listener objects:
OTVConnectLicensePreDelivery connectLicensePreDelivery = new OTVConnectLicensePreDelivery(callback, connectPreDeliveryListener);
To pre-fetch the license asynchronously:
connectLicensePreDelivery.fetchLicense();
If the pre-fetch is successful, the OTVConnectLicensePreDeliveryListener.onSuccess(int numLicense)
will be called.
OTVConnectLicensePreDelivery will provision the device automatically before pre-fetching if it has not yet been provisioned.
Once the licence is fetched, the connectLicensePreDelivery
object should be released:
connectLicensePreDelivery.release();