← audioPreferred capture in getDisplayMedia API
v152 · dictionary member · screen capture
DisplayMediaStreamOptions.audioSelection
A dictionary member of the options argument to navigator.mediaDevices.getDisplayMedia(). When set to "preferred" — the only value of its enum — it signals that the application would like the user agent to steer the user toward sharing audio along with the screen video. It is a hint: the user agent MAY ignore it, and it never overrides the user's choice in the picker.
syntax
enum AudioSelectionPreferenceEnum { "preferred" };
dictionary DisplayMediaStreamOptions {
(boolean or MediaTrackConstraints) video = true;
(boolean or MediaTrackConstraints) audio = false;
// ... CaptureController, selfBrowserSurface, systemAudio,
// windowAudio, surfaceSwitching, monitorTypeSurfaces ...
AudioSelectionPreferenceEnum audioSelection; // no default
};
// Use:
navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true,
audioSelection: "preferred"
});
The IDL above quotes the Screen Capture Working Draft of 23 July 2026 verbatim for the enum and the member line. Chromium ships the identical member, gated [RuntimeEnabled=GetDisplayMediaAudioSelection] in media_stream_constraints.idl, with the flag stable at trunk (2026-07-28).
Specification text for the member, verbatim: “If present, signals whether the application would like the user agent to steer the user towards sharing audio along with the video. The user agent MAY ignore this hint.” The enum is described as “Describes whether an application invoking getDisplayMedia() would like the user agent to prefer capturing audio along with the video”, with its single value "preferred" meaning “The application prefers that the user agent prioritize capturing audio along with the video.”
value
| Type | AudioSelectionPreferenceEnum (a WebIDL enum, i.e. a DOMString restricted to the enumerated values) |
|---|---|
| Valid values | "preferred" — the only enumerated value (2026-07-28). The enum is deliberately extensible: future values could express other preferences, but none exist today |
| Default | None — the member has no default in the dictionary. Absent means no preference expressed, which is distinct from any future “exclude”-style value |
| Case sensitivity | Exact match required ("preferred", lowercase) per WebIDL enum semantics |
| Companion requirement | Meaningful only when audio capture is also requested (audio: true or an audio constraints object). With audio not requested, no audio control exists in the picker and the hint has no observable effect in Chrome |
observable effect
getDisplayMedia() still returns a Promise<MediaStream>; the member introduces no new return values, events, or readable state. Its effect is on the picker the browser shows before the promise settles (desktop Chrome, verified at trunk 2026-07-28):
- the system/window audio toggle starts checked instead of unchecked;
- the confirm button reads “Share with Audio” while audio is on, “Share” when off;
- if the user switches audio off, an audio recommendation banner appears in the picker;
- the audio toggle renders in a boxed style with simplified labels.
If the user accepts with audio on, the resolved MediaStream contains an audio track (stream.getAudioTracks().length > 0); if they decline, it does not — the promise itself settles identically in both cases, so applications must check the track list rather than infer from the hint.
errors and edge behavior
| Situation | Behavior |
|---|---|
Any string other than "preferred" (e.g. "yes", "Preferred") | TypeError from WebIDL enum conversion, rejecting the getDisplayMedia() call before any picker opens — the single-value enum makes every other string invalid |
Non-string values (true, 1, {}) | Converted to a string first per WebIDL; the result is not "preferred", so the same TypeError applies (undefined and a missing member are exempt — they mean “absent”) |
| Browser without the feature | No error: unknown dictionary members are ignored per WebIDL, so the call proceeds with historical picker defaults. Degradation is silent and safe |
audio absent or false | No error; the hint has no observable effect because the picker offers no audio control (Chrome behavior, trunk) |
| UA declines to honor the hint | Explicitly allowed (“The user agent MAY ignore this hint”) — not an error path; the app observes only the final track list |
| User dismisses the picker | Standard getDisplayMedia rejection (NotAllowedError), unchanged by this feature |
context and requirements
- Where it can appear — only inside the options dictionary of
navigator.mediaDevices.getDisplayMedia()(secure contexts only, with thedisplay-capturePermissions Policy applying to the call). It is not a track constraint: it does not appear inMediaTrackSupportedConstraints,MediaTrackSettings, orgetCapabilities(). - Which picker it affects — Chrome applies the hint only when the media picker was opened for a
getDisplayMedia()request (RequestSource::kGetDisplayMedia); the legacychrome.desktopCaptureextension flow is unaffected. - Platform — the steered UI is Chrome's desktop (Views) media picker; the ChromeStatus record lists a desktop-152 milestone only, with no Android or WebView milestone (2026-07-28).
- User activation — the Screen Capture specification requires transient user activation for
getDisplayMedia(); Chromium's enforcement of that requirement is still gated by the separate experimental flagGetDisplayMediaRequiresUserActivationat trunk, so call it from a user gesture regardless.
lifecycle
- Parse — Blink converts the options dictionary; a present
audioSelectionis validated against the enum (invalid strings throwTypeErrorhere, before anything is shown). - Plumb — the preference travels as
audio_selection_preferredfrom Blink throughStreamControlsto the browser process'sMediaStreamRequest(the blink-side change is CL 8107082). - Picker construction — the desktop picker reads the preference once, when the dialog is built: screen/window audio toggles start checked, the boxed toggle style is selected, and the confirm-button label tracker is armed.
- User decision — toggling audio updates the button label live; turning audio off under a
"preferred"hint surfaces the recommendation banner. The user may still share without audio. - Settlement — the promise resolves with whatever the user approved; the hint leaves no persistent state. Each
getDisplayMedia()call re-evaluates a fresh options dictionary — the hint is per-call, not sticky, and there is nothing to reset or revoke afterward.
examples
Complete pattern — request, hint, and verify the outcome rather than assuming it:
async function startCoWatch() {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true,
audioSelection: "preferred"
});
if (stream.getAudioTracks().length === 0) {
// User declined audio despite the hint. The spec allows this;
// fall back or stop, but do not retry-prompt in a loop.
const proceed = confirm("No audio was shared. Continue video-only?");
if (!proceed) {
stream.getTracks().forEach(t => t.stop());
return null;
}
}
return stream;
}
Invalid values fail fast — useful to know when building the options object dynamically:
// TypeError: "yes" is not a valid AudioSelectionPreferenceEnum
await navigator.mediaDevices.getDisplayMedia({
video: true, audio: true, audioSelection: "yes"
});
browser compatibility
Interim table. No BCD entry exists for audioSelection (BCD api/MediaDevices.json has no audioSelection subfeature; there is no DisplayMediaStreamOptions.json at all — verified 2026-07-28). Compiled from primary sources:
| Browser | Support | Evidence |
|---|---|---|
| Chrome (desktop) | 152 | milestone=152 listing (Enabled by default); launch CL 8138688 |
| Chrome (Android/WebView) | Not recorded | No milestone on the ChromeStatus record |
| Edge | Not separately reported | Chromium-based; no separate record |
| Firefox | No position recorded — member ignored | ChromeStatus record (no Mozilla view); WebIDL dictionary semantics |
| Safari | No signal — member ignored | WebKit standards-positions #696 (open, unlabelled 2026-07-28) |
No upstream WPT coverage exists for the member: the wpt/screen-capture/ directory contains no audioSelection test (directory listing verified 2026-07-28).
security and privacy
- The member is an input-only hint: it grants no capability, requests no track by itself, and exposes nothing readable back to script (no settings, no supported-constraint entry).
- The user keeps the final say — Chrome pre-selects audio but never locks it, and warns the user (recommendation banner) when they turn audio off against the hint.
- The explainer's privacy analysis: no new user-facing controls are needed because audio sharing beside video already existed; the change only influences presentation of an existing choice.
- Abuse considerations: a site could pass the hint on every call to make audio sharing look pre-endorsed — mitigated by the picker remaining a per-call, user-driven consent surface with the banner making the manipulation visible.