---
title: "Supporting PlayReady SL3000 on Windows Chrome"
description: "This guide details the integration and support for PlayReady Security Level 3000 (SL3000) on Windows Chrome browsers."
---
> For the complete documentation index, see [llms.txt](/llms.txt).

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.

## Prerequisites

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

### System 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.

### Codec Support

*   **H.264:** Natively supported.
*   **HEVC:** Supported, but requires the [HEVC Video Extensions](https://www.microsoft.com/en-us/p/hevc-video-extensions/9nmzlz57r3t7) installed from the Microsoft Store.
*   **AV1:** Currently in development/experimental status.

## Implementation Configuration

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

### Key System String and Robustness

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.

:::caution

**Key ID Byte Order**

PlayReady on Chrome follows the EME specification for Key IDs (same as Widevine). However, legacy PlayReady implementations (e.g., on Edge or IE) often use a different GUID byte order.

If your existing license server or client logic expects the specific "Microsoft GUID" byte order used by Edge, you may need to update your logic to support the standard UUID format used by Chrome.

:::

### Handling Hardware Context Reset

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.

#### Browser Behavior

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.

#### Implementation Requirement

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.

### Open Source Player Configuration

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

#### Shaka Player

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

```javascript
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'
    }
}
```

#### Video.js (videojs-contrib-eme)

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.

```javascript
// 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
}
```

## Capability Query Examples

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

### Checking H.264 Support

```javascript
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);
  }
}
```

### Checking HEVC Support

*Ensure HEVC extensions are installed on Windows.*

```javascript
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
}
```

## Troubleshooting

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

### 1. Browser Flags

Ensure hardware secure decryption is enabled in Chrome settings:

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

### 2. Media Internals

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.

### 3. Windows HWDRM Reset

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`.

### 4. Codec Installation

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

```powershell
get-appxpackage *hevc* | Select-Object Version
get-appxpackage *av* | Select-Object Version
```