JavaScript Navigator requestMediaKeySystemAccess() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
✅ Baseline Widely available
🔒 Secure context

What You’ll Learn

navigator.requestMediaKeySystemAccess() is the Encrypted Media Extensions (EME) entry point for DRM / Clear Key playback. Learn key systems, configuration arrays, MediaKeySystemAccess, five examples, and try-it labs on HTTPS.

01

Kind

Method

02

Returns

Promise<MediaKeySystemAccess>

03

Status

Baseline Widely available

04

Context

Secure (HTTPS)

05

API family

Encrypted Media Extensions

06

Next step

createMediaKeys()

Introduction

Streaming sites often protect video with encryption. Browsers expose the Encrypted Media Extensions (EME) API so a page can ask for a media key system, create keys, and decrypt playback in a <video> element.

requestMediaKeySystemAccess(keySystem, supportedConfigurations) is usually the first call: “Can this browser satisfy one of these configs for this key system?”

💡
No Dep / Exp / Non-standard banner

MDN marks Baseline Widely available (since March 2019). It is not Deprecated, Experimental, or Non-standard. It does require a secure context.

Understanding the requestMediaKeySystemAccess() Method

  • Two argumentskeySystem string and a non-empty supportedConfigurations array.
  • Promise result — fulfills with MediaKeySystemAccess.
  • First match wins — the first satisfiable configuration object is used.
  • Capabilities — list audio and/or video contentType MIME strings (not both empty).
  • Timing — call near when you will create / use MediaKeys.
  • Permissions Policy — may be blocked by encrypted-media policy (SecurityError).

📝 Syntax

General form of the method:

JavaScript
navigator.requestMediaKeySystemAccess(keySystem, supportedConfigurations)

Parameters

  • keySystem — string such as "org.w3.clearkey" or a vendor system id.
  • supportedConfigurations — non-empty array of configuration objects (init data types, audio/video capabilities, persistence options, and more).

Return value

  • A Promise that fulfills with a MediaKeySystemAccess object.

Common rejections

  • NotSupportedError — key system or configs not supported.
  • TypeError — empty keySystem or empty configurations array.
  • SecurityError — blocked by Permissions Policy encrypted-media.

MDN-style Clear Key sketch

JavaScript
const clearKeyOptions = [
  {
    initDataTypes: ["keyids", "webm"],
    audioCapabilities: [
      { contentType: 'audio/webm; codecs="opus"' },
      { contentType: 'audio/webm; codecs="vorbis"' }
    ],
    videoCapabilities: [
      { contentType: 'video/webm; codecs="vp9"' },
      { contentType: 'video/webm; codecs="vp8"' }
    ]
  }
];

const access = await navigator.requestMediaKeySystemAccess(
  "org.w3.clearkey",
  clearKeyOptions
);
// Next: const mediaKeys = await access.createMediaKeys();

⚡ Quick Reference

GoalCode
Feature detecttypeof navigator.requestMediaKeySystemAccess === "function"
Request accessawait navigator.requestMediaKeySystemAccess(id, configs)
Clear Key id"org.w3.clearkey"
Inspect configaccess.getConfiguration()
Create keysawait access.createMediaKeys()
Secure context?window.isSecureContext

🔍 At a Glance

Four facts to remember about navigator.requestMediaKeySystemAccess().

Returns
Promise

MediaKeySystemAccess

Status
Baseline

Widely available

Context
HTTPS

Secure required

API
EME

Encrypted media

📋 Clear Key vs Commercial DRM

Clear Key (org.w3.clearkey)Commercial DRM
PurposeLearning / simple encrypted demosProduction streaming protection
License serverOften app-managed keysVendor license service
Beginner demosIdeal starting pointNeeds extra accounts / SDKs
Same entry APIrequestMediaKeySystemAccessSame method, different keySystem

Examples Gallery

Examples stay beginner-friendly: detect EME, request Clear Key access, inspect the chosen configuration, and create MediaKeys. Full DRM playback still needs encrypted media + licenses beyond this page.

📚 Getting Started

Detect EME support and request Clear Key access.

Example 1 — Feature Detection

Confirm the method and secure context before requesting access.

JavaScript
const lines = [
  "requestMediaKeySystemAccess: " +
    (typeof navigator.requestMediaKeySystemAccess === "function"
      ? "available"
      : "missing"),
  "isSecureContext: " + window.isSecureContext
];
console.log(lines.join("\n"));
Try It Yourself

How It Works

If the method is missing or the context is insecure, skip encrypted playback UI.

Example 2 — Request Clear Key Access (MDN)

Ask for org.w3.clearkey with webm audio/video capabilities.

JavaScript
async function requestClearKeyAccess() {
  if (typeof navigator.requestMediaKeySystemAccess !== "function") {
    return "EME API not supported";
  }
  const clearKeyOptions = [
    {
      initDataTypes: ["keyids", "webm"],
      audioCapabilities: [
        { contentType: 'audio/webm; codecs="opus"' },
        { contentType: 'audio/webm; codecs="vorbis"' }
      ],
      videoCapabilities: [
        { contentType: 'video/webm; codecs="vp9"' },
        { contentType: 'video/webm; codecs="vp8"' }
      ]
    }
  ];
  try {
    const access = await navigator.requestMediaKeySystemAccess(
      "org.w3.clearkey",
      clearKeyOptions
    );
    return "access ok: " + access.keySystem;
  } catch (err) {
    return "Error: " + err.name;
  }
}

requestClearKeyAccess().then(console.log);
Try It Yourself

How It Works

The browser picks the first configuration it can satisfy from your array.

📈 Practical Patterns

Inspect the chosen config, create MediaKeys, and wrap errors safely.

Example 3 — Inspect getConfiguration()

After access is granted, read the configuration the browser selected.

JavaScript
async function showChosenConfig() {
  const options = [
    {
      initDataTypes: ["cenc", "keyids", "webm"],
      videoCapabilities: [
        { contentType: 'video/mp4; codecs="avc1.42E01E"' },
        { contentType: 'video/webm; codecs="vp8"' }
      ],
      audioCapabilities: [
        { contentType: 'audio/mp4; codecs="mp4a.40.2"' },
        { contentType: 'audio/webm; codecs="opus"' }
      ]
    }
  ];
  const access = await navigator.requestMediaKeySystemAccess(
    "org.w3.clearkey",
    options
  );
  const cfg = access.getConfiguration();
  return JSON.stringify({
    keySystem: access.keySystem,
    initDataTypes: cfg.initDataTypes,
    videoCount: (cfg.videoCapabilities || []).length,
    audioCount: (cfg.audioCapabilities || []).length
  });
}

showChosenConfig().then(console.log).catch((err) => {
  console.log("Error: " + err.name);
});
Try It Yourself

How It Works

Use the returned config to confirm codecs before attaching keys to a media element.

Example 4 — createMediaKeys()

Typical next step after access: create a MediaKeys object for the media element.

JavaScript
async function createClearKeyMediaKeys() {
  const access = await navigator.requestMediaKeySystemAccess("org.w3.clearkey", [
    {
      initDataTypes: ["keyids", "webm"],
      videoCapabilities: [{ contentType: 'video/webm; codecs="vp8"' }],
      audioCapabilities: [{ contentType: 'audio/webm; codecs="opus"' }]
    }
  ]);
  const mediaKeys = await access.createMediaKeys();
  return "MediaKeys created: " + (mediaKeys ? "yes" : "no");
}

createClearKeyMediaKeys().then(console.log).catch((err) => {
  console.log("Error: " + err.name);
});
Try It Yourself

How It Works

Production players then call video.setMediaKeys(mediaKeys) and handle license messages.

Example 5 — Safe Access Helper

Centralize detection, empty-input checks, and common EME errors.

JavaScript
async function requestMediaKeySystemAccessSafe(keySystem, configs) {
  if (typeof navigator.requestMediaKeySystemAccess !== "function") {
    return { ok: false, access: null, reason: "unsupported" };
  }
  if (!window.isSecureContext) {
    return { ok: false, access: null, reason: "insecure-context" };
  }
  if (!keySystem || !configs || !configs.length) {
    return { ok: false, access: null, reason: "TypeError-inputs" };
  }
  try {
    const access = await navigator.requestMediaKeySystemAccess(
      keySystem,
      configs
    );
    return { ok: true, access: access, reason: "ok" };
  } catch (err) {
    return { ok: false, access: null, reason: err.name };
  }
}

const demoConfigs = [
  {
    initDataTypes: ["webm"],
    videoCapabilities: [{ contentType: 'video/webm; codecs="vp8"' }],
    audioCapabilities: [{ contentType: 'audio/webm; codecs="opus"' }]
  }
];

requestMediaKeySystemAccessSafe("org.w3.clearkey", demoConfigs).then((r) => {
  console.log(JSON.stringify({
    ok: r.ok,
    reason: r.reason,
    keySystem: r.access ? r.access.keySystem : null
  }));
});
Try It Yourself

How It Works

Structured results make it easy to show a non-DRM fallback without crashing the player UI.

🚀 Common Use Cases

  • Protected video streaming — unlock DRM-protected VOD / live streams.
  • Clear Key demos — teach EME without a commercial DRM contract.
  • Codec capability probing — discover which encrypted configs the UA accepts.
  • Player bootstrap — first step before createMediaKeys() and license exchange.
  • Fallback planning — detect unsupported DRM early and offer alternate streams.

🧠 How requestMediaKeySystemAccess() Works

1

Choose a key system

For example Clear Key or a commercial DRM system id.

keySystem
2

Describe capabilities

Pass a non-empty array of configs (codecs, init data types, persistence).

Configs
3

Get MediaKeySystemAccess

The Promise resolves when the browser can satisfy a config.

Access
4

Create MediaKeys

Call createMediaKeys(), attach to video, handle licenses.

📝 Notes

Universal Browser Support

navigator.requestMediaKeySystemAccess() is Baseline Widely available (MDN: since March 2019) as part of Encrypted Media Extensions. It requires a secure context. Actual DRM system ids (Widevine, PlayReady, FairPlay) still vary by browser and platform — always feature-detect and catch NotSupportedError.

Baseline · Widely available

Navigator.requestMediaKeySystemAccess()

Promise → MediaKeySystemAccess for EME / DRM encrypted media.

Universal Widely available
Google Chrome EME Baseline · Widevine common
Full support
Mozilla Firefox EME Baseline · system-dependent DRM
Full support
Microsoft Edge EME Baseline · Chromium / PlayReady paths
Full support
Apple Safari EME Baseline · FairPlay typical
Full support
Opera EME Baseline · Chromium-based
Full support
Internet Explorer Legacy EME differs — prefer modern browsers
Legacy
requestMediaKeySystemAccess() Excellent

Bottom line: Detect the method on HTTPS, request a supported key system with non-empty configs, then createMediaKeys() and handle license flow or fall back.

Conclusion

navigator.requestMediaKeySystemAccess() is the Baseline gateway into Encrypted Media Extensions. Start with Clear Key for learning, pass non-empty capability configs on HTTPS, then create MediaKeys when you are ready to decrypt playback.

Continue with requestMIDIAccess(), mediaDevices, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Call only on HTTPS / localhost
  • Pass a non-empty configurations array
  • Include valid contentType codec strings
  • Request access close to createMediaKeys()
  • Catch NotSupportedError and offer fallback media

❌ Don’t

  • Pass empty keySystem or empty configs
  • Leave both audio and video capabilities empty
  • Assume every DRM system id exists everywhere
  • Trigger prompts on every page load unnecessarily
  • Ignore Permissions Policy encrypted-media blocks

Key Takeaways

Knowledge Unlocked

Five things to remember about requestMediaKeySystemAccess()

Baseline EME entry point — request a key system, then create MediaKeys.

5
Core concepts
02

Status

Baseline

Widely available
🎬 03

Family

EME / DRM

Encrypted media
🛠 04

Needs

configs + HTTPS

Non-empty
🔑 05

Next

createMediaKeys()

Playback

❓ Frequently Asked Questions

It asks the browser for access to a media key system (DRM / Clear Key). If a matching configuration is supported, the Promise resolves to a MediaKeySystemAccess object you can use to create MediaKeys for decrypting encrypted media.
No. MDN marks it Baseline Widely available (since March 2019). It is not Deprecated, Experimental, or Non-standard — no status banner is required. It does require a secure context (HTTPS / localhost).
Clear Key is a simple key system defined for EME testing and non-proprietary encrypted media. Real streaming services often use commercial systems such as Widevine, PlayReady, or FairPlay (browser-dependent).
Near the time you will create and use MediaKeys — not randomly on page load. The call may trigger user-visible permission or resource prompts.
The Promise rejects with NotSupportedError when the key system is missing or none of the supportedConfigurations can be satisfied (for example unsupported codecs).
Either audioCapabilities or videoCapabilities may be empty, but not both. Each capability needs a valid contentType MIME string (include codecs parameters when required).
Did you know?

Clear Key (org.w3.clearkey) is part of the EME ecosystem so developers can practice encrypted playback without a commercial DRM vendor. Production apps still choose a platform-supported commercial system when required.

Explore requestMIDIAccess() Next

Connect MIDI keyboards and controllers with the Web MIDI API.

requestMIDIAccess() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful