Skip to content

Supporting PlayReady SL3000 on Windows Chrome

This guide details the integration and support for PlayReady Security Level 3000 (SL3000) on Windows Chrome browsers. PlayReady SL3000 utilizes the hardware-based DRM path in Windows to protect high-value content (such as 4K/UHD, HDR, and HEVC).

Historically available only on Microsoft Edge, this feature enables hardware-secure playback on Google Chrome for Windows 11 users.

To utilize PlayReady SL3000, the end-user environment and the implementation must meet the following requirements.

  • Operating System: Windows 11 21H2 (Build 22000) or later.
  • Browser: Chrome version 140.0.7339.0 or higher.
  • Hardware: Valid GPU drivers supporting PlayReady SL3000.
  • Architecture Limitations:
    • Supported: x64 (native)
    • Not Supported: x86 builds, ARM64 builds, or x86_64 builds running on ARM64 via WoW emulation.
  • H.264: Natively supported.
  • HEVC: Supported, but requires the HEVC Video Extensions installed from the Microsoft Store.
  • AV1: Currently in development/experimental status.

To target the PlayReady SL3000 key system in Chrome, specific EME (Encrypted Media Extensions) configurations are required.

It is recommended to set the key system and robustness as below:

  • Key system string: com.microsoft.playready.recommendation.3000
  • Video/Audio robustness: leave as empty

The key system string itself contains hardware-level robustness enforcement, eliminating the need for separate robustness settings.

A unique challenge with PlayReady SL3000 is the Hardware Context Reset. This occurs when the secure media path is interrupted by system events, such as:

  • The device entering or waking from sleep mode (e.g., closing/opening a laptop lid).
  • Connecting a new monitor or changing graphics topology.

When this happens, the decryption keys are lost, and the browser cannot automatically resume playback without intervention.

When a reset occurs:

  1. The browser closes all MediaKeySession objects with the reason "hardware-context-reset".
  2. The media element fires a waitingforkey event.
  3. Playback stalls.

Your player application must listen for these events and handle the recovery logic.

Recovery Strategy:

  1. Monitor the MediaKeySession.closed promise.
  2. Check if the reason is hardware-context-reset.
  3. If confirmed, you must re-create the MediaKeySession, request a new license, and update the media element.
  4. Alternatively, reload the player instance or prompt the user to press “Play” to restart the session.

If you are using popular open-source players, specific configurations are required to map the key systems correctly.

Shaka Player may default to the standard PlayReady key system. You must explicitly map the key system to the SL3000 string.

drm: {
servers: {
'com.microsoft.playready': 'YOUR_LICENSE_URL',
},
keySystemsMapping: {
// Map standard PlayReady to the SL3000 specific string
'com.microsoft.playready': 'com.microsoft.playready.recommendation.3000'
}
}

When using the specific SL3000 key system, the browser sends the full <PlayReadyKeyMessage> XML in the request body. Some license servers may expect only the <Challenge> data. You may need to parse the message in the getLicense callback.

// Pseudocode for getLicense callback implementation
getLicense: function(emeOptions, keyMessage, callback) {
// 1. Parse 'keyMessage' (XML)
// 2. Extract content inside <Challenge> tag
// 3. Send extracted challenge to License Server
}

To verify support before initializing playback, use navigator.mediaCapabilities.decodingInfo.

async function checkPlayReadySL3000H264() {
const config = {
type: 'media-source',
video: {
contentType: 'video/mp4; codecs="avc1.4d401f"', // Adjust profile/level as needed
width: 1920, height: 1080, bitrate: 2000000, framerate: 30
},
keySystemConfiguration: {
keySystem: 'com.microsoft.playready.recommendation.3000', // SL3000 Key System
persistentStateRequired: 'true', // Required for SL3000
video: { robustness: "" } // Empty or "3000"
}
};
try {
const result = await navigator.mediaCapabilities.decodingInfo(config);
if (result.supported && result.keySystemAccess) {
console.log('PlayReady SL3000 H.264 is supported.');
} else {
console.log('PlayReady SL3000 H.264 is NOT supported.');
}
} catch (e) {
console.error('Capability check failed', e);
}
}

Ensure HEVC extensions are installed on Windows.

async function checkPlayReadySL3000HEVC() {
const config = {
type: 'media-source',
video: {
contentType: 'video/mp4; codecs="hvc1.1.6.L93.B0"', // Adjust HEVC codec string
width: 1920, height: 1080, bitrate: 2000000, framerate: 30
},
keySystemConfiguration: {
keySystem: 'com.microsoft.playready.recommendation.3000',
persistentStateRequired: 'true',
video: { robustness: "" }
}
};
// ... Execute decodingInfo as shown above
}

If playback fails or the Key System is not detected, check the following:

Ensure hardware secure decryption is enabled in Chrome settings:

  • Navigate to chrome://flags/#enable-hardware-secure-decryption
  • Set to Enabled.

Use Chrome’s internal logging to debug CDM loading and errors:

  • CDM Info: chrome://media-internals#cdms
    • Search for com.microsoft.playready.recommendation.
  • Playback Logs: chrome://media-internals#players
    • Check for PIPELINE_ERROR_DECODE or license exchange failures.

In rare cases of fatal errors, Windows may automatically disable HWDRM. To re-enable it manually via console (if testing):

  1. Create a session of type MF_MEDIAKEYSESSION_TYPE_PERSISTENT_USAGE_RECORD.
  2. Call Load with the session ID: ResetHardwareDRMDisabled 1.0.

To verify installed codecs on Windows, run the following in PowerShell:

Terminal window
get-appxpackage *hevc* | Select-Object Version
get-appxpackage *av* | Select-Object Version