javascriptroom blog

Which Camera Does getUserMedia API Open on Mobile Devices? Front or Rear? (And Do You Need Code to Select?)

In an era where web applications increasingly rely on real-time media—from video calls and virtual try-ons to QR code scanners and mobile photography—the ability to control camera access is critical. The getUserMedia API, a cornerstone of WebRTC (Web Real-Time Communication), enables web apps to access a user’s camera and microphone directly in the browser. But for mobile users, a common question arises: When you call getUserMedia, which camera does it open by default—front (selfie) or rear (environment)? And can you control this without writing code?

This blog dives deep into the default behavior of getUserMedia on mobile devices, why it varies, and how to explicitly select front or rear cameras using code. By the end, you’ll understand how to tailor camera access to your app’s needs, whether you’re building a video chat tool (front camera) or a barcode scanner (rear camera).

2025-11

Table of Contents#

  1. What is the getUserMedia API?
  2. Default Camera Behavior on Mobile Devices: Front or Rear?
  3. Why the Default Camera Might Vary
  4. Do You Need Code to Select Front/Rear Camera?
  5. Step-by-Step: Selecting a Specific Camera with Code
  6. Common Pitfalls and Troubleshooting
  7. Conclusion
  8. References

What is the getUserMedia API?#

The getUserMedia API is part of the Media Capture and Streams API and allows web applications to request access to a user’s media input devices (cameras, microphones) and receive a MediaStream (a stream of audio/video data).

Basic Syntax#

To use getUserMedia, you call navigator.mediaDevices.getUserMedia() with a set of constraints (e.g., video resolution, audio enable/disable). Here’s a minimal example to access the camera:

// Request access to the camera (video only)
navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    // Attach the stream to a <video> element
    const videoElement = document.getElementById('video');
    videoElement.srcObject = stream;
  })
  .catch(error => {
    console.error('Camera access failed:', error);
  });

This code will prompt the user for camera permission. If granted, it displays the camera feed in a <video> element. But which camera is it using?

Default Camera Behavior on Mobile Devices: Front or Rear?#

The short answer: Most mobile browsers default to the front (selfie) camera when using getUserMedia with basic video constraints.

Why Front by Default?#

The front camera is the de facto default for common use cases like video calls (e.g., Zoom, Google Meet) or social media selfies—scenarios where users expect to see themselves. Browsers prioritize this to align with user intent for typical web apps.

Exceptions and Variability#

However, the default behavior is not standardized by the W3C spec. Some browsers or devices may default to the rear camera in niche cases, but this is rare. For example:

  • Older Android browsers (pre-2018) sometimes defaulted to the rear camera.
  • Some low-end devices with limited camera hardware may only have a front camera, making it the only option.

Key Takeaway: Never assume the default camera is consistent across all devices or browsers. Always test, and use explicit selection for reliability.

Why the Default Might Vary#

Several factors influence the default camera selection:

1. Browser Vendor Decisions#

Browsers like Chrome, Safari, and Firefox prioritize user experience for common workflows. Since video calling (front camera) is the most frequent use case for getUserMedia, they default to front to minimize friction.

2. User Permission History#

Some browsers remember previous permissions. For example, if a user previously allowed a site to access the rear camera, the browser might reuse that preference. However, this behavior is inconsistent across vendors.

3. Device-Specific Hardware#

Devices with only one camera (e.g., some budget phones) will default to that single camera, regardless of facing.

4. Use Case Inference#

A few browsers attempt to infer intent from context. For example, if your app requests high-resolution video (e.g., 4K), the browser might prioritize the rear camera (which often has better sensors). But this is not reliable.

Do You Need Code to Select Front/Rear Camera?#

Yes. To guarantee front or rear camera access, you must use code to explicitly select the desired camera. Relying on defaults is risky due to variability across devices and browsers.

The solution lies in using media constraints—specifically the facingMode property—to tell getUserMedia which camera to access.

Step-by-Step: Selecting a Specific Camera with Code#

To select front or rear cameras, follow these steps:

Step 1: Understand facingMode Constraints#

The facingMode constraint in getUserMedia specifies the camera’s facing direction. The possible values are:

  • 'user': Front camera (selfie).
  • 'environment': Rear camera (points outward).
  • 'left'/'right': For devices with left/right-facing cameras (rare).

You can pass facingMode directly in the constraints object to request a specific camera.

Step 2: Basic Selection (Quick Method)#

For simple cases, you can set facingMode in the constraints to force front or rear:

Example: Force Rear Camera#

// Request rear camera (environment-facing)
const constraints = {
  video: {
    facingMode: { exact: 'environment' } // 'exact' ensures strict matching
  }
};
 
navigator.mediaDevices.getUserMedia(constraints)
  .then(stream => {
    document.getElementById('video').srcObject = stream;
  })
  .catch(error => {
    console.error('Rear camera access failed:', error); // e.g., no rear camera
  });

Example: Force Front Camera#

// Request front camera (user-facing)
const constraints = {
  video: {
    facingMode: 'user' // 'exact' optional here; 'user' is default for most
  }
};
 
navigator.mediaDevices.getUserMedia(constraints)
  .then(stream => { /* ... */ });

Step 3: Advanced Selection (Enumerate Devices)#

For more control (e.g., selecting a specific camera by name or handling multiple cameras), use mediaDevices.enumerateDevices() to list all available media devices, then filter by type and facing.

Workflow:#

  1. Request permission to access cameras (required to get device details).
  2. Enumerate all media devices.
  3. Filter for video input devices (kind: 'videoinput').
  4. Check device labels or facingMode to identify front/rear.

Code Example: Enumerate and Select Rear Camera#

async function selectRearCamera() {
  try {
    // Step 1: Request permission (required to access device labels)
    await navigator.mediaDevices.getUserMedia({ video: true });
 
    // Step 2: Enumerate all media devices
    const devices = await navigator.mediaDevices.enumerateDevices();
 
    // Step 3: Filter video input devices
    const videoDevices = devices.filter(device => device.kind === 'videoinput');
 
    if (videoDevices.length === 0) {
      throw new Error('No cameras found.');
    }
 
    // Step 4: Find rear camera (environment-facing)
    // Use device label (e.g., "Rear Camera") or facingMode (more reliable)
    const rearCamera = videoDevices.find(device => {
      // Note: device.facingMode is not always available; fallback to label parsing
      return device.facingMode === 'environment' || 
             device.label.toLowerCase().includes('rear') || 
             device.label.toLowerCase().includes('environment');
    });
 
    if (!rearCamera) {
      throw new Error('Rear camera not found.');
    }
 
    // Step 5: Access the rear camera by device ID
    const constraints = {
      video: { deviceId: rearCamera.deviceId }
    };
 
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    document.getElementById('video').srcObject = stream;
 
  } catch (error) {
    console.error('Error selecting rear camera:', error);
  }
}
 
// Call the function
selectRearCamera();

Key Notes:#

  • facingMode vs. Device ID: facingMode is simpler and preferred for most cases. Use device ID only if you need to select a specific camera (e.g., choosing between two rear cameras).
  • exact Constraint: Adding exact: true (e.g., facingMode: { exact: 'environment' }) ensures the browser strictly enforces the facing mode. Without exact, the browser may fall back to any available camera if the requested one isn’t found.
  • Device Labels: Device labels (e.g., "Front Camera (0)") are user-friendly but locale-dependent (e.g., "Cámara frontal" in Spanish). Avoid relying solely on labels; facingMode is more reliable.

Common Pitfalls and Troubleshooting#

1. HTTPS Requirement#

getUserMedia only works over HTTPS (or localhost for development). Mobile browsers block camera access on HTTP sites to protect user privacy.

2. Browser Compatibility#

  • iOS Safari: Supports facingMode in iOS 11+.
  • Android Chrome: Supports facingMode in Chrome 52+.
  • Older browsers (e.g., IE) do not support getUserMedia at all.

Check caniuse.com for the latest stats.

3. Missing Permissions#

Device labels and facingMode are only available after the user grants camera permission. Always request basic video access first before enumerating devices.

4. No Camera Available#

Handle cases where the requested camera doesn’t exist (e.g., a tablet with only a front camera). Use .catch() to fall back to the default camera.

5. OverconstrainedError#

If you request conflicting constraints (e.g., 4K resolution + front camera on a device with low-res front camera), the browser throws an OverconstrainedError. Use ideal instead of exact for flexibility:

video: {
  facingMode: 'environment',
  width: { ideal: 1920 }, // Request 1080p ideally, but allow lower
  height: { ideal: 1080 }
}

Conclusion#

The getUserMedia API defaults to the front camera on most mobile devices, but this behavior is not standardized. To reliably select front or rear cameras, you must use code to set the facingMode constraint (e.g., 'user' for front, 'environment' for rear). For advanced control, enumerate devices and filter by deviceId or labels.

By explicitly specifying the camera via constraints, you ensure a consistent experience across devices and browsers, critical for apps like QR scanners (rear) or video chat (front).

References#