Configure

Camera & microphone

Choose capture sources, configure the devices websites see, grant origin permissions, and capture media with your existing automation client.

On this page

Use a camera, OBS Virtual Camera, or microphone as an input, then choose the device names and camera output modes visible to your page. The SDK configures the browser Context; your existing client runs the page and its ordinary navigator.mediaDevices calls.

First follow SDK setup for your language. This guide assumes the SDK and your chosen automation client are installed. See runtime management to select an executable or release, and Contexts and ownership for session cleanup.

These examples require Mimic 0.2.4 or later; the SDK downloads a compatible runtime automatically. Media inputs must be available to the machine running Mimic. A device connected only to a remote automation client is not a local input to that runtime.

Capture with your client

Each example selects the default camera and microphone, falling back to the first available source of each kind. It exposes them as Studio Camera and Studio Microphone, grants capture to https://example.com, prints the resulting track settings, and stops every track before closing the session.

To use OBS, start its virtual camera and select its video source by the label returned during discovery. Keep the microphone selection independent: a virtual camera does not supply an audio input automatically.

Language
Browser client

Requires available camera and microphone sources. The source supplies capture; labels and groups define the devices the site sees.

Create files

media.mjs
import { launch } from "mimic-browser/playwright";

const session = await launch();
try {
  const context = await session.newContext({
    media: async ({ browserContextId, mimic }) => {
      const { sources } = await mimic.getMediaSources({ browserContextId });
      const choose = (kind) => sources.find(s => s.kind === kind && s.default)
        ?? sources.find(s => s.kind === kind);
      const camera = choose("videoinput");
      const microphone = choose("audioinput");
      if (!camera || !microphone) throw new Error("Capture source unavailable");
      return {
        seed: "meeting-devices",
        devices: [
          {
            key: "camera", kind: "videoinput",
            source: { sourceId: camera.sourceId },
            label: "Studio Camera", group: "desk",
            modes: [{ width: 640, height: 480, frameRate: 30 }],
            defaultMode: { width: 640, height: 480, frameRate: 30 },
            processing: { resize: "crop-and-scale" },
          },
          {
            key: "microphone", kind: "audioinput",
            source: { sourceId: microphone.sourceId },
            label: "Studio Microphone", group: "desk",
          },
        ],
      };
    },
  });
  await context.grantPermissions(["camera", "microphone"], { origin: "https://example.com" });
  const page = await context.newPage();
  await page.goto("https://example.com");
  console.log(await page.evaluate(async () =>
    (await navigator.mediaDevices.enumerateDevices()).map(device => device.toJSON())
  ));
} finally {
  await session.close();
}

Run

Run the example
node media.mjs

Choose the input; define the public device

A capture source provides actual frames or audio samples. A media profile defines the logical devices exposed by enumerateDevices(), track labels, settings, and camera capabilities. Changing a public label does not change which source supplies the data.

Call Mimic.getMediaSources for the new Context inside the media factory. Discovery returns a private label, kind, default flag, and opaque sourceId; it does not open a camera or microphone. Use that ID in the device's source selector. For a chosen native label, require exactly one match and report a missing or ambiguous source.

Treat source IDs as temporary, Context-bound handles. Discover them again for a new Context or runtime; do not save them as portable device identifiers. They are different from the origin-scoped deviceId returned to web content. Native labels, paths, and source IDs stay in the automation interface; configured pages receive the public device identity.

key
A unique logical name such as camera or microphone within your configured catalog.
label
The public device and track name. Permission-dependent label redaction still applies before capture permission is granted.
group
Give a camera and microphone the same group to associate their public identities. If omitted, the group defaults to the device key.
seed
Makes generated recipe selection repeatable. It does not make web device IDs interchangeable between origins or Contexts, and it does not preserve a private source binding across runtime launches.

A configured catalog exposes only its listed inputs. An empty devices array exposes no capture inputs; leaving media unconfigured retains native enumeration. A missing configured source is omitted rather than silently replaced with an unlisted device.

Configure before creating your page

The SDK's Context helper accepts a media configuration or a factory. Use a factory when selecting discovered sources: it receives the new browser Context ID and a Mimic command client, then returns the media configuration before any application Page is created. The framework's own Context and Page objects remain the ones your application uses.

  1. Create the Context through the SDK helper.
  2. Discover sources for that Context inside the factory.
  3. Return the complete public device catalog.
  4. Grant permission for the intended origin, then open the page and capture.

Always supply browserContextId when issuing media commands for a non-default Context. Omitting it selects the runtime's default Context, even when the command is sent through a Page session. Source discovery and profile validation perform no capture. If a factory or configuration fails, the SDK disposes the Context it just created.

Grant permission to the page's origin

Defining a media profile does not grant camera or microphone access. The examples use Browser.grantPermissions with the new browserContextId, the exact origin, and videoCapture / audioCapture. Change the origin together with the page URL when adapting the example to your application.

Use an HTTPS page or a trustworthy local origin for navigator.mediaDevices. Wait for navigation before evaluating capture code. Unset or denied permissions reject immediately in automation; no interactive permission prompt is required. Revoking permission ends the affected tracks and their clones.

Set camera output modes

Every explicit camera in devices needs a nonempty modes list and a defaultMode that exactly matches one of its entries. Add the following fields to the camera device to offer VGA and HD output, with HD selected by default:

Camera output fields
{
  "modes": [
    { "width": 640, "height": 480, "frameRate": 30 },
    { "width": 1280, "height": 720, "frameRate": 30 }
  ],
  "defaultMode": { "width": 1280, "height": 720, "frameRate": 30 },
  "processing": { "resize": "crop-and-scale" }
}

processing.resize: "crop-and-scale" lets Mimic produce the declared output by cropping or scaling native frames. Without it, a custom camera recipe must use a single mode with supported native geometry. An explicit device's optional profile bounds its supplied recipe; it does not fill in missing modes. The separate camera shorthand expands presets automatically. Choose either shorthand or devices in a configuration, never both.

Profile validation checks the recipe without opening hardware and returns nativeModesVerified: false. Actual source support is checked when capture starts. The source must sustain the recipe's maximum nominal frame rate; scaling a frame adds no detail, and Mimic does not duplicate frames to manufacture a higher capture rate.

A catalog can contain up to 16 devices and each camera up to 64 modes. Dimensions must be integers from 1 to 8192, with at most 16 megapixels per frame; frame rates must be from 1 to 120 FPS. These are recipe limits, not a guarantee that a particular source can supply every accepted mode.

Microphones accept source, identity, and grouping fields. Camera modes and video processing do not apply to audio inputs. Audio settings reflect the capture backend; a public microphone label does not add echo cancellation, noise suppression, or other signal processing.

Request and inspect the actual output

Use ordinary getUserMedia() constraints to select a public device and output, then inspect track.getSettings(). The examples request exact public device IDs so capture cannot choose a different listed input. Required output constraints must be feasible; ideal values express a preference among feasible outputs.

track.applyConstraints() uses the same output selection rules. Impossible requests reject with OverconstrainedError and preserve the previous settings and output. A clone shares its native input but can select a different supported output. A declared base geometry reports resizeMode: "none"; an adapted geometry reports "crop-and-scale", even when processing is enabled for both.

Facing direction is not inferred. Required facingMode, zoom, focus, exposure, white balance, torch, PTZ, and ImageCapture controls are outside the supported camera contract. Generic presets describe physical device classes; they do not certify the behavior of a particular camera model or driver.

Stop capture before replacing the catalog

Stop every track in a finally block, including clones your application created. Then close the owned Page or Context and the SDK session. Closing a session created with connect leaves the shared runtime running; a session created with launch also owns its runtime process.

Catalog replacement is atomic and rejects while capture in that Context is opening, active, or finishing cleanup. A rejected replacement preserves the old catalog. Wait for capture teardown before configuring it again. Navigation closes the departing document's capture while retaining the Context's catalog for subsequent pages.

When capture fails

  • No matching source: inspect discovery results from the same Context. Confirm the camera or virtual camera is running on the runtime's machine, and use the actual input label when selecting a specific source.
  • Profile rejected: check unique keys, source selectors, complete camera modes, and an exact matching default mode. Remove video processing fields from microphone devices.
  • Media API unavailable or permission denied: wait for the correct secure page to load and grant permission to its origin in the same Context.
  • Capture cannot start: validation does not prove native mode support. Read private source diagnostics and Mimic.getMediaProfile diagnostics through the automation client; web-visible errors intentionally omit private backend details.
  • Profile update rejected: stop every original and cloned track, let backend cleanup finish, and retry only after capture is closed.

Continue with the SDK reference for typed media commands, or Contexts and ownership to combine media with an environment profile and resource settings.