JavaScript Navigator mediaCapabilities Property

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline

What You’ll Learn

navigator.mediaCapabilities is the entry point for the Media Capabilities API. Learn decodingInfo / encodingInfo, the supported · smooth · powerEfficient result flags, adaptive media tips, five examples, and try-it labs.

01

Kind

Read-only property

02

Returns

MediaCapabilities

03

Baseline

Widely available

04

Decode

decodingInfo()

05

Encode

encodingInfo()

06

Result

supported · smooth · power

Introduction

Streaming apps often ask: Can this device play H.264 1080p smoothly without draining the battery? Older helpers like canPlayType() only give a rough “maybe.”

navigator.mediaCapabilities returns a MediaCapabilities object. You pass a media configuration (codec, bitrate, resolution, and so on) to decodingInfo() or encodingInfo() and get a Promise with three booleans: supported, smooth, and powerEfficient.

💡
Pick the best stream, not just any stream

Use the API before choosing a quality ladder rung — prefer a lower bitrate when smooth or powerEfficient is false, even if the format is technically supported.

Understanding the mediaCapabilities Property

Think of it as a “media hardware interview” for the browser: you describe a clip, and it answers whether it can play (or encode) that clip well.

  • Entry pointnavigator.mediaCapabilities (also on WorkerNavigator).
  • Main methodsdecodingInfo(config) and encodingInfo(config).
  • Config — includes type ("file", "media-source", …) plus audio and/or video details.
  • Result flagssupported, smooth, powerEfficient.
  • Baseline — Widely available across modern browsers (MDN, since about January 2020).

📝 Syntax

General form of the property:

JavaScript
navigator.mediaCapabilities

Value

  • A MediaCapabilities object with decodingInfo() and encodingInfo().

Common patterns

JavaScript
// Feature detect:
if ("mediaCapabilities" in navigator) {
  // Media Capabilities API available
}

// MDN-style audio decoding check:
navigator.mediaCapabilities
  .decodingInfo({
    type: "file",
    audio: {
      contentType: "audio/mp3",
      channels: 2,
      bitrate: 132700,
      samplerate: 5200
    }
  })
  .then(function (result) {
    console.log("supported:", result.supported);
    console.log("smooth:", result.smooth);
    console.log("powerEfficient:", result.powerEfficient);
  });

⚡ Quick Reference

GoalCode
Get the API objectnavigator.mediaCapabilities
Feature detect"mediaCapabilities" in navigator
Decode checknavigator.mediaCapabilities.decodingInfo(config)
Encode checknavigator.mediaCapabilities.encodingInfo(config)
Result fieldssupported, smooth, powerEfficient
Status (MDN)Baseline Widely available

🔍 At a Glance

Four facts to remember about navigator.mediaCapabilities.

Returns
MediaCapabilities

API entry

Baseline
widely

Since ~Jan 2020

Async
Promise

decodingInfo

Answers
3 flags

support · smooth · power

📋 mediaCapabilities vs canPlayType()

mediaCapabilitiescanPlayType()
QuestionSupported + smooth + power efficient?Can the element play this type?
Answer shapeBooleans via Promise"" / "maybe" / "probably"
Detail levelCodec, bitrate, size, framerate…Mostly MIME / codec string
Best forAdaptive streaming quality choiceQuick “is this MIME OK?” checks
MDN guidanceMedia Capabilities improves on canPlayType / isTypeSupported for quality decisions

Examples Gallery

Examples follow MDN Media Capabilities patterns with decodingInfo. Prefer Try It Yourself — results depend on your device and browser.

📚 Getting Started

Detect the API and run the classic MDN audio check.

Example 1 — Feature Detection

Check whether navigator.mediaCapabilities exists before calling it.

JavaScript
const supported = "mediaCapabilities" in navigator;
console.log(supported
  ? "Media Capabilities API available"
  : "Media Capabilities API missing");
Try It Yourself

How It Works

On modern Baseline browsers the property is present. Always detect in shared libraries for older environments.

Example 2 — Audio decodingInfo (MDN)

Ask whether an MP3-style audio configuration is supported, smooth, and power efficient.

JavaScript
navigator.mediaCapabilities
  .decodingInfo({
    type: "file",
    audio: {
      contentType: "audio/mp3",
      channels: 2,
      bitrate: 132700,
      samplerate: 5200
    }
  })
  .then(function (result) {
    console.log(
      "This configuration is " +
      (result.supported ? "" : "not ") + "supported,"
    );
    console.log((result.smooth ? "" : "not ") + "smooth, and");
    console.log(
      (result.powerEfficient ? "" : "not ") + "power efficient."
    );
  });
Try It Yourself

How It Works

This mirrors MDN’s sample: pass a type plus an audio description, then read the three result flags.

📈 Practical Patterns

Video checks, quality picking, and a reusable helper.

Example 3 — Video Decoding Check

Test a common H.264 / AVC configuration for media-source style playback.

JavaScript
navigator.mediaCapabilities
  .decodingInfo({
    type: "media-source",
    video: {
      contentType: 'video/mp4; codecs="avc1.42E01E"',
      width: 1920,
      height: 1080,
      bitrate: 2000000,
      framerate: 30
    }
  })
  .then(function (result) {
    console.log(JSON.stringify({
      supported: result.supported,
      smooth: result.smooth,
      powerEfficient: result.powerEfficient
    }));
  });
Try It Yourself

How It Works

Include resolution, bitrate, and framerate so the browser can judge real playback cost — not just the codec string.

Example 4 — Pick a Quality Ladder Rung

Compare two video configs and prefer the one that is supported and smooth.

JavaScript
async function pickVideo() {
  const mc = navigator.mediaCapabilities;
  const low = {
    type: "file",
    video: {
      contentType: 'video/mp4; codecs="avc1.42E01E"',
      width: 640,
      height: 360,
      bitrate: 800000,
      framerate: 30
    }
  };
  const high = {
    type: "file",
    video: {
      contentType: 'video/mp4; codecs="avc1.42E01E"',
      width: 1920,
      height: 1080,
      bitrate: 4000000,
      framerate: 30
    }
  };
  const [a, b] = await Promise.all([
    mc.decodingInfo(low),
    mc.decodingInfo(high)
  ]);
  if (b.supported && b.smooth) return "1080p";
  if (a.supported) return "360p";
  return "unsupported";
}

pickVideo().then(function (choice) {
  console.log("chosen: " + choice);
});
Try It Yourself

How It Works

Query several ladder rungs in parallel, then pick the highest that stays supported and smooth (optionally also power efficient).

Example 5 — Decode Result Helper

Wrap detection and decodingInfo into one friendly summary object.

JavaScript
async function describeDecode(config) {
  if (!("mediaCapabilities" in navigator)) {
    return { ok: false, reason: "unsupported" };
  }
  try {
    const r = await navigator.mediaCapabilities.decodingInfo(config);
    return {
      ok: true,
      supported: r.supported,
      smooth: r.smooth,
      powerEfficient: r.powerEfficient,
      score:
        (r.supported ? 1 : 0) +
        (r.smooth ? 1 : 0) +
        (r.powerEfficient ? 1 : 0)
    };
  } catch (err) {
    return {
      ok: false,
      reason: String(err.name || "Error"),
      message: String(err.message || err)
    };
  }
}

describeDecode({
  type: "file",
  audio: {
    contentType: "audio/mp3",
    channels: 2,
    bitrate: 132700,
    samplerate: 5200
  }
}).then(function (summary) {
  console.log(JSON.stringify(summary));
});
Try It Yourself

How It Works

Centralize feature detection, await the Promise, and catch TypeErrors from invalid configs so your player UI can fall back cleanly.

🚀 Common Use Cases

  • Adaptive streaming — choose ABR ladder rungs that stay smooth on this device.
  • Battery-aware video — prefer powerEfficient configs on mobile.
  • Codec negotiation — decide between AVC, VP9, AV1, or HEVC per client.
  • Recording / encoding — use encodingInfo before MediaRecorder or WebCodecs pipelines.
  • Worker-side checks — run capability queries off the main thread via WorkerNavigator.

🧠 How navigator.mediaCapabilities Works

1

You describe a media config

Type, codecs, size, bitrate, channels, framerate…

Config
2

Call decodingInfo / encodingInfo

The browser estimates capability for that config.

Query
3

Promise returns three flags

supported, smooth, powerEfficient.

Result
4

You choose a better stream

Serve a format that plays well on this device.

📝 Notes

  • Baseline Widely available (MDN, since about January 2020).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Also available on WorkerNavigator.mediaCapabilities.
  • Results are estimates — still verify playback in real streaming tests.
  • Related: mediaDevices, maxTouchPoints, JavaScript hub.

Universal Browser Support

navigator.mediaCapabilities is Baseline Widely available across modern browsers (MDN: since about January 2020). Use decodingInfo / encodingInfo to choose media that stays smooth and power efficient.

Baseline · Widely available

Navigator.mediaCapabilities

Query decode/encode ability for a config, then pick streams using supported, smooth, and powerEfficient.

Universal Widely available
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
mediaCapabilities Excellent

Bottom line: Feature-detect, call decodingInfo with a realistic config, and fall back when supported or smooth is false.

Conclusion

navigator.mediaCapabilities opens the Media Capabilities API. Pass a media configuration to decodingInfo or encodingInfo, read supported / smooth / powerEfficient, and choose a stream that fits the device — not just one that “might” play.

Continue with mediaDevices, maxTouchPoints, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect with "mediaCapabilities" in navigator
  • Include realistic bitrate, size, and framerate in configs
  • Prefer smooth + powerEfficient rungs on mobile
  • Catch errors from invalid configuration objects
  • Keep a playable fallback when the best rung fails

❌ Don’t

  • Rely only on canPlayType for quality decisions
  • Assume every device reports the same flags for AV1 / HEVC
  • Block the UI — await the Promise asynchronously
  • Treat estimates as absolute lab measurements
  • Skip testing on real low-end phones

Key Takeaways

Knowledge Unlocked

Five things to remember about mediaCapabilities

Baseline Media Capabilities entry — query decode/encode quality before streaming.

5
Core concepts
🔊 02

Method

decodingInfo

Decode
03

Flags

3 booleans

Result
📈 04

Use

Pick streams

ABR
05

Status

Baseline

Wide

❓ Frequently Asked Questions

It is a read-only Navigator property that returns a MediaCapabilities object. You use decodingInfo() and encodingInfo() to ask whether a media configuration is supported, smooth, and power efficient.
No. MDN marks it Baseline Widely available (since about January 2020). It is not Deprecated, Experimental, or Non-standard.
supported means the browser can handle the configuration. smooth means playback should stay fluid at that quality. powerEfficient means decoding/encoding is expected to use hardware efficiently and save battery when possible.
HTMLMediaElement.canPlayType() and MediaSource.isTypeSupported() mainly answer “maybe / probably / yes.” Media Capabilities also estimates smoothness and power efficiency so you can pick a better stream, not only a playable one.
Yes. WorkerNavigator also exposes mediaCapabilities, so you can run capability checks off the main thread.
No. It is read-only. You call methods on the MediaCapabilities object; you do not assign a new value to navigator.mediaCapabilities.
Did you know?

MDN positions Media Capabilities as an upgrade over canPlayType() and MediaSource.isTypeSupported() — because “playable” is not the same as “smooth and battery-friendly.”

Explore mediaDevices Next

Learn getUserMedia and device listing for cameras and microphones.

mediaDevices →

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