v144 · webrtc · demo

Multi-Source Switcher

Enumerate every camera on the device and switch the live stream source mid-call — no page reload, no permission prompt loop. This is the real-time device-switching use case that a future <usermedia> element would handle declaratively.

Origin trial / flag The native <usermedia> element is behind chrome://flags/#enable-experimental-web-platform-features in Chrome 144. This demo uses navigator.mediaDevices.getUserMedia() + enumerateDevices() so device switching works in every browser. The <usermedia> support badge below shows whether the element is registered in your current build.
<usermedia> element: checking…
click “start camera” to begin

available cameras

no cameras enumerated yet — click “start camera” first (permission required for device labels)
active track settings
resolution
frameRate
facingMode
deviceId
displayedAt

the API

// 1. enumerate video inputs (requires permission for labels)
const devices = await navigator.mediaDevices.enumerateDevices();
const cameras = devices.filter(d => d.kind === 'videoinput');

// 2. switch to a specific device
async function switchTo(deviceId) {
  if (currentStream) currentStream.getTracks().forEach(t => t.stop());
  currentStream = await navigator.mediaDevices.getUserMedia({
    video: {
      deviceId: { exact: deviceId },
      width:  { ideal: 1280 },
      height: { ideal: 720 }
    }
  });
  videoEl.srcObject = currentStream;
}

// 3. inspect track settings after stream is live
video.onloadedmetadata = () => {
  const track = currentStream.getVideoTracks()[0];
  const s = track.getSettings();
  console.log(s.width, s.height, s.frameRate, s.facingMode, s.deviceId);
};

// 4. react to device changes (plug/unplug)
navigator.mediaDevices.addEventListener('devicechange', enumerate);

// Future declarative form (<usermedia> element):
// <usermedia kind="video" deviceid="abc123">Switch camera</usermedia>

how it works

The first getUserMedia call grants permission and unlocks device labels. After that, enumerateDevices() returns human-readable names instead of empty strings. Switching cameras re-calls getUserMedia with deviceId: { exact: id } — the constraint tells the browser exactly which physical device to open. The old stream is stopped first to release the hardware lock. The devicechange event fires when cameras are plugged in or out, triggering a fresh enumeration.

see also