This article describes setting up a plugin for the castLabs DRMtoday service in Wowza Streaming Engine™ media server software. With this plugin, you can automatically deliver secured MPEG-DASH and HLS video content from your Wowza Streaming Engine media server.
The DRMtoday service provides licensing for all major DRM systems, enabling you to adopt multiple studio-recognized DRM systems from the single plugin integration. Version 3.1.0 of the DRMtoday plugin also includes key rotation support. For more, see how the DRMtoday licensing service works.
Wowza Streaming Engine 4.5.0 or later is required for this functionality.
Streaming secured content using DRMtoday
If the DRMtoday plugin for Wowza Streaming Engine is set up correctly, it automatically encrypts all content delivered from the application for which it's configured. When a player requests the stream's manifest for the first time, the Wowza Streaming Engine application becomes active, and the DRMtoday plugin ingests the Common Encryption (CENC) key pair for the application.
Stream security in error cases
You may encounter instances when the key ingestion into DRMtoday fails, for example, due to network disruptions such as limited access to the drmtoday.com domain or DRMtoday outages. In those cases, the plugin can't stop the streaming process facilitated by the Wowza Streaming Engine application.
To maintain protection in these circumstances, encryption is activated, and an error message is written to the wowzastreamingengine_error log file in [install-dir]/logs. Since DRMtoday doesn't recognize the key in this scenario, the player can't request a valid decryption key, and playback fails. This ensures that unencrypted content never leaves the Wowza media server.
Before you start
- Ensure your Wowza Streaming Engine server has HTTPS access to fe.drmtoday.com, auth.drmtoday.com, and their staging variants fe.staging.drmtoday.com and auth.staging.drmtoday.com. Be aware that the IP addresses change with each DRMtoday deployment.
- Create your application in Wowza Streaming Engine. Do not enable any kind of encryption yet.
- Configure two key seeds in DRMtoday. One is used as the dt_keyseed_id and the other as the dt_ivseed_id. You can add these values from your DRMtoday dashboard under Configuration > Key seeds. See the Server-side key derivation section for more details.
- Do not specify the streaming method applicable. Do not enable Adobe HDS, RTMP, or RTSP/RTP.
Install the DRMtoday plugin
Follow these steps to get the latest version of the plugin and add it to your Wowza Streaming Engine installation.
- Use your castLabs account to log in to the castLabs Download Portal.
- Download drmtoday-wowza-plugin-[latest-version].jar to the lib folder of your Wowza Streaming Engine installation ([install-dir]/lib). Make sure that only one version of the plugin is deployed.
Please contact DRMtoday support, your DRMtoday technical contact, or your DRMtoday sales representative to get access to the Wowza Streaming Engine plugin.
Add the DRMtoday module
To use the DRMtoday service for secure streaming, add the following module definition to your live or VOD streaming application in Wowza Streaming Engine. See Configure modules for steps to accomplish this task.
Name | Description | Fully Qualified Class Name |
---|---|---|
DRMtoday | DRMtoday | com.castlabs.drmtoday.wowza.v2.module.ModuleDRMtoday |
Configure the DRMtoday module
After adding the DRMtoday plugin to the Modules list in Wowza Streaming Engine, adjust the default settings for the plugin by adding properties to the application configuration in Wowza Streaming Engine Manager. This task can also be completed using the Application.xml.
- On the Applications tab in Wowza Streaming Engine Manager, click the application name in the contents panel.
- On the application details page, click the Properties tab.
- In the Quick Links bar, click Custom.
- In the Custom properties section, click Edit.
- For each property in the following tables, click the Add Custom Property button. Specify the indicated property settings in the Add Custom Property dialog box, then click Add.
- Click to Save after configuring your parameters. Then, restart the application to apply the changes.
Set required configuration parameters
If you need help with the terminology in the following tables, refer to the DRMtoday glossary in the castLabs documentation. You must log in with a DRMtoday account to access the glossary.
Path
|
Name
|
Type
|
Value and description
|
/Root/Application | dt_user | String | The ingest API account user from the Members / Users page in DRMtoday. To minimize abuse and password leaks, create a single Wowza media server API user that gets ingest rights. |
/Root/Application | dt_password | String | The dt_user password for the API account user in DRMtoday. |
/Root/Application | dt_merchant | String | Your merchant API name at DRMtoday. You can find the API name on the My organizations page in DRMtoday. |
/Root/Application | dt_env | String | The DRMtoday environment, either STAGING or PROD. |
/Root/Application | dt_keyseed_id | String | The ID of the keyseed that's used to derive the keys. You can find this value from your DRMtoday Dashboard under Configuration > Key seeds.
Important: You must configure a key seed in DRMtoday for use with this property. See Server-side key derivation for more.
|
/Root/Application | dt_ivseed_id | String | The ID of the keyseed that's used to derive the Initialization Vectors (IVs) for Apple FairPlay license delivery. You can find this value from your DRMtoday dashboard under Configuration > Key seeds.
Important: You must configure an IV seed in DRMtoday for use with this property. See Server-side key derivation for more.
|
/Root/Application | dt_cupertino_encryption_method | String | Specifies one of the following encryption methods for HLS streams:
|
/Root/Application | cupertinoEncryptionAPIBased | Boolean | Set to true. |
Set optional configuration parameters
Path
|
Name
|
Type
|
Value and description
|
/Root/Application | dt_assetid_pattern | String | The pattern used as the input for dt_assetid_format anddt_variantid_format .For example, you can use a pattern such as .*_(.*).mp4. See Asset ID patterns for more details. |
/Root/Application | dt_assetid_format | String | The format string that uses the capturing groups from the dt_assetid_pattern as input to construct the resulting assetId .For example, you can use a format string such as asset_{cg1}, where {cg1} is replaced by the output of the first capturing group of the dt_assetid_pattern . See Asset ID patterns for more details. |
/Root/Application | dt_variantid_format | String | The format string that uses the capturing groups from the dt_assetid_pattern as input to construct the resulting variantId . See Asset ID patterns for more details. |
/Root/Application | dt_keyrotation | Boolean | Set to true to enable key rotation. The default value is false. |
/Root/Application | dt_keyrotation_interval | Integer | The default value is 3600. See Key rotation for more details. |
Debug the DRMtoday module
If you need to debug the DRMtoday plugin, manually edit the log4j-config properties file for your Wowza Streaming Engine server. You can find this XML file in the conf folder of your Wowza Streaming Engine installation ([install-dir]/conf).
- To continue, modify the <Configuration>/<Appenders> container by adding the following section:
<RollingFile name="serverAll" fileName="${sys:com.wowza.wms.ConfigHome}/logs/wowzastreamingengine_all.log" filePattern="${sys:com.wowza.wms.ConfigHome}/logs/wowzastreamingengine_all.%d{yyyy-MM-dd}.log"> <PatternLayout> <Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n</Pattern> <AlwaysWriteExceptions>false</AlwaysWriteExceptions> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> </Policies> <DefaultRolloverStrategy> <Delete basePath="${sys:com.wowza.wms.ConfigHome}/logs" maxDepth="1"> <IfLastModified age="5d" /> </Delete> </DefaultRolloverStrategy> </RollingFile>
- Update the <Root> section in the <Configuration>/<Loggers> container, by adding:
<AppenderRef ref="serverAll" level="info"/>
Also add this line to the <Configuration>/<Loggers> container:
<Logger name="com.castlabs.drmtoday" level="info"/>
The final <Configuration>/<Loggers> container should look similar to this:
<Loggers> <Logger name="com.castlabs.drmtoday" level="info"/> <Root level="info"> <AppenderRef ref="stdout" level="info"/> <AppenderRef ref="serverAccess" level="info"/> <AppenderRef ref="serverError" level="warn"/> <AppenderRef ref="serverAll" level="info"/> <!-- <AppenderRef ref="serverStats" level="info"/> --> <!-- <AppenderRef ref="vhostAccess" level="info"/> --> <!-- <AppenderRef ref="vhostError" level="warn"/> --> <!-- <AppenderRef ref="applicationAccess" level="info"/> --> <!-- <AppenderRef ref="applicationError" level="warn"/> --> <!-- <AppenderRef ref="applicationInstanceAccess" level="info"/> --> <!-- <AppenderRef ref="applicationInstanceError" level="warn"/> --> </Root> </Loggers>
Alternatively, you can set the logger level to debug, which may generate very verbose output. For more, see Enable debug logging for Wowza Streaming Engine.
Learn more about DRMtoday configurations
Asset ID construction
The assetId
used to ingest the keys to DRMtoday is derived from the channel name like this:
<wowza_application_name>_<content_file_name>
Asset ID patterns
Some asset IDs may be too long, making them more difficult to use for authentication. In such cases, it's possible to configure a pattern matching the asset ID as it's taken from the stream name. The output of the capturing groups for this pattern can be used as the input for a format string, allowing you to construct a desired asset ID.
To use the asset ID feature, configure at least the dt_assetid_pattern and the dt_assetid_format.
Capturing groups from the dt_assetid_pattern
can be referenced in the dt_assetid_format
string using {cg} and the capturing group number. For example, the first capturing group would be {cg1}, the second would be {cg2}, and so on.
The find method locates the pattern in the input string, matching any portion of the assetId
string. You can use this site to test how Java behaves. Paste your examples and leave all options unchecked. When testing, the find() column should contain a Yes value. The last column displays the content of the capturing groups with the number that can be used in the format string.
Example usage
Let's take an example assetId
of vod2_asset_pattern_sample.mp4.
- Configure the
dt_assetid_pattern
to .*_(.*).mp4. - Configure the
dt_assetid_format
to format_asset_{cg1}. - The string
sample
now matches the first capturing group. The format string result is format_asset_sample.
Server-side key derivation
Starting with the DRMtoday Wowza Streaming Engine plugin version 2.0.0, key derivation is handled server side. See Key seed-based ingest for details and to learn how to configure the required key seeds in DRMtoday.
Note: When configuring the dt_keyseed_id and the dt_ivseed_id in the DRMtoday Dashboard, please copy the ID values and add them to your Wowza Streaming Engine application. The ID is the generated UUID string. Make sure you're not using the seed itself.
Here's an example of how the key seeds appear in the Application.xml for a given application:
<Property> <Name>dt_keyseed_id</Name> <Value>01234567-89ab-cdef-0123-456789abcdef</Value> <Type>String</Type> </Property> <Property> <Name>dt_ivseed_id</Name> <Value>fedcba98-7654-3210-fedc-ba9876543210</Value> <Type>String</Type> </Property>
Multikey support
The DRMtoday Wowza Streaming Engine plugin supports generating multiple keys for different profiles of live content. Multikey support for VOD content is not available currently.
By default, each quality referenced in a SMIL file for adaptive live streaming is ingested to DRMtoday as an independent asset with a unique assetId
and video and audio streamType
.
To ingest multiple sources with the same assetId
but a different streamType
, source names should match the following pattern:
(.*)_ _DT_ _(UHD|HD|SD|AUDIO|VIDEO|VIDEO_AUDIO)_.*
Example usage
Let's assume that the Wowza Streaming Engine application used for live streaming is called live, and we have the following adaptive live.smil:
<?xml version="1.0" encoding="UTF-8"?> <smil title="Live"> <body> <switch> <video src="live__DT__SD_.stream"> <param name="videoBitrate" value="1024000" valuetype="data"></param> </video> <video src="live__DT__HD_.stream"> <param name="videoBitrate" value="8192000" valuetype="data"></param> </video> </switch> </body> </smil>
With the setup in this example, DRMtoday ingests the following two entries:
assetId
: live_live,streamType
: SD,Key ID
: {keyId1} → for the first entry in the SMIL fileassetId
: live_live,streamType
: HD,Key ID
: {keyId2} → for the second entry in the SMIL file
Key rotation
Version 3.1.0 of the DRMtoday plugin adds support for key rotation. This enhances security and minimizes vulnerabilities by allowing you to rotate keys that encrypt content over time.
Within DRMtoday, a specific keyRotationId
can be identified in addition to the assetId
. It's important that this ID progresses sequentially, allowing DRMtoday to provide the existing key and subsequent key during a licensing request.
The system can look up the next key by incrementing the current keyRotationId
value by one. This step is important to make sure the player transitions to the new key seamlessly, without any interruptions.
Due to this sequential requirement, the keyRotationId
can't just be any increasing number. It's typically calculated by dividing the current time by a set interval. For this purpose, it's important to differentiate between a live application and a VOD application in Wowza Streaming Engine.
The next two sections describe the different key rotation considerations based on application type.
Live key rotation
For live applications, the keyRotationId
is calculated by dividing the system time (in Unix epoch seconds) by the value set for the dt_keyrotation_interval. Using the system time guarantees a continuously incrementing key rotation ID, even after the Wowza Streaming Engine server is restarted.
The streaming server generates a keyRotationId
roughly for every chunk duration of the video. Therefore, the dt_keyroration_interval
should be equal to or greater than the chunk duration. This ensures that the calculation of the key rotation ID returns the last keyRotationId,
or it's incremented by one.
The interval setting impacts the frequency of license requests to DRMtoday, so avoid setting this too low. By default, it's set to 3600 or a one-hour interval. Even if the configured value is lower, the suggested minimum for the dt_keyrotation_interval
is 30 seconds. This minimum value prevents key rotation IDs that are too high and rotation intervals that are too low. The 30-second minimum should only be used for testing. In production environments, this value should be significantly higher.
VOD key rotation
In contrast, VOD applications call for the key rotation ID to be determined using the chunkId
, not the system time. This ensures that every time a video begins, identical video chunks are encrypted with the same key from the start. Since the starting chunkId
is zero, the first keyRotationId
is also zero.
For VOD, the dt_keyrotation_interval parameter isn't directly tied to the time interval in seconds, so the chunk interval must be considered. To find the appropriate dt_keyrotation_interval
value, use the following formula:
dt_keyrotation_interval = desired_interval_in_seconds / chunk_duration
Example usage
Let's assume the desired interval is 3600 seconds, and the chunk duration is 10 seconds. The dt_keyrotation_interval
can be set to 360.