{"id":439,"date":"2024-07-01T16:07:58","date_gmt":"2024-07-01T16:07:58","guid":{"rendered":"https:\/\/blog.mozilla.org\/webrtc\/?p=439"},"modified":"2025-07-04T00:50:08","modified_gmt":"2025-07-04T00:50:08","slug":"how-webrtc-speaker-selection-works","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/","title":{"rendered":"How WebRTC speaker selection works"},"content":{"rendered":"<p><meta name=\"twitter:image\" content=\"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakerFirstHalf.png\"><\/p>\n<p>Today&#8217;s topic is <em>speaker selection<\/em>. If you&#8217;ve never given it much thought, or consider it straightforward, this post is for you. Let&#8217;s start by testing your general WebRTC knowledge:<\/p>\n<p style=\"padding-left: 40px;\"><strong>Pop Quiz:<\/strong> If a website wants to play out of different speakers on your system, what permission must it have?<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li>Speaker-selection permission<\/li>\n<li>Microphone permission<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>If you answered 2 then chances are you know your WebRTC stuff well, but you&#8217;re probably on a Chromium browser.<\/p>\n<p>Pause for a moment. Why would websites need <em><strong>microphone<\/strong><\/em> permission to control speaker <em>output<\/em>? Why should users expose themselves to possibly being recorded just to redirect songs to their portable speakers? They shouldn&#8217;t. It&#8217;s a permission escalation and an entirely unnecessary invasion of privacy. Nevertheless, in other browsers this remains the only answer today.<\/p>\n<p>Thankfully, Firefox provides the more straightforward and privacy-preserving answer of 1.<\/p>\n<p>In this post, we&#8217;ll look at how speaker selection works in different browsers, how permissions can be abused for fingerprinting purposes, and how to add speaker selection with a fallback so it works in all browsers.<br \/>\n<!--more--><\/p>\n<h2>How speaker selection works in Firefox (and the spec)<\/h2>\n<p>On desktop, Firefox supports the standards-track <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaDevices\/selectAudioOutput\"><code>navigator.mediaDevices.selectAudioOutput()<\/code><\/a> API. You only need a <code>&lt;button&gt;<\/code> to invoke it:<\/p>\n<pre>\r\nspeakers.onclick = async () =&gt; {\r\n  const info = await navigator.mediaDevices.selectAudioOutput();\r\n  await videoElement.setSinkId(info.deviceId);\r\n  speakers.innerText = `${info.label}...`;\r\n  localStorage.previouslyUsedSpeakersId = info.deviceId;\r\n}\r\n<\/pre>\n<p>Passing in a previously used <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaDevices\/selectAudioOutput#deviceid\"><code>deviceId<\/code><\/a> you wish to use is optional, but allows you to skip a prompt in most cases.<\/p>\n<p>If you&#8217;re in Firefox right now, you can put on your headset and try it here:<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/jan-ivar.github.io\/dummy\/picker_output.html\" allow=\"speaker-selection\" width=\"100%\" height=\"300px\" frameborder=\"0\"><span style=\"display: inline-block; width: 0px; overflow: hidden; line-height: 0;\" data-mce-type=\"bookmark\" class=\"mce_SELRES_start\">\ufeff<\/span><span style=\"display: inline-block; width: 0px; overflow: hidden; line-height: 0;\" data-mce-type=\"bookmark\" class=\"mce_SELRES_start\">\ufeff<\/span><\/iframe><br \/>\nPressing the button brings up Firefox&#8217;s speaker picker and updates to reflect your choice. Press the reset button that appears on the page to go back to the dynamic OS default. For non-Firefox users reading this article, or if you&#8217;re on your phone, here&#8217;s what this looks like in Firefox on desktop:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" width=\"2604\" height=\"1058\" src=\"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png\" alt=\"Two Firefox windows. The first showing its built-in speaker picker drop-down with 3 speaker choices: AirPods, Macbook Pro Speakers and Marley Get Together. The second window is after the prompt, and shows two buttons: Speakers: Marley Get Together, and a reset button\" class=\"alignright size-full wp-image-459\" srcset=\"https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png 2604w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-250x102.png 250w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-700x284.png 700w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-768x312.png 768w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-1536x624.png 1536w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-2048x832.png 2048w, https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4-120x49.png 120w\" sizes=\"(max-width: 2604px) 100vw, 2604px\" \/><br \/>\nAnd yes, my external Bluetooth speakers really are named &#8220;Marley Get Together&#8221;!<\/p>\n<p>Users can sometimes change their speakers through the OS as well, but each website decides how to handle this. I will continue to hear the demo page playing through &#8216;Marley Get Together&#8217; until I press the reset button. At that point it goes back to the current OS default. This is illustrative of the API. The demo page stores your choice in local storage. Note that Firefox has a <a href=\"https:\/\/bugzil.la\/1879204\">bug<\/a> where it doesn&#8217;t yet fire a <code>devicechange<\/code> event when the OS default speakers for Firefox are changed.<\/p>\n<h3>Strong privacy characteristics<\/h3>\n<p>Notably, this demo is from a different origin and runs here in an <code>iframe<\/code> with <a href=\"https:\/\/www.w3.org\/TR\/audio-output\/#dfn-speaker-selection\"><code>allow=\"speaker-selection\"<\/code><\/a> as the only permission policy delegated to it. It therefore <em>cannot listen to you while you&#8217;re reading this<\/em>. I wish it were hypothetical, but this blog site quite possibly has access to your microphone already from previous posts you&#8217;ve interacted with \u2014 that is, unless you&#8217;re a first-time reader, in which case welcome, and never mind! \u2014 note, Firefox does not persist permission unless you ask it to, but some other browsers do.<\/p>\n<p>Moreover, the API adheres to the <a href=\"https:\/\/www.w3.org\/Privacy\/IG\/\">W3C Privacy Interest Group<\/a> and <a href=\"https:\/\/tag.w3.org\/\">W3C Technical Architecture Group<\/a>&#8216;s <a href=\"https:\/\/www.w3.org\/TR\/design-principles\/#device-enumeration\">design principle<\/a> of not exposing device information of unused devices.<\/p>\n<p>This seems like a slam dunk API. So, why <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaDevices\/selectAudioOutput#browser_compatibility\">hasn&#8217;t it been broadly implemented<\/a> yet? Let&#8217;s look at that.<\/p>\n<h2>The microphone loophole<\/h2>\n<p>Unfortunately, cameras and microphones (which are about input not output) are exposed through an older API. That API <a href=\"https:\/\/www.w3.org\/TR\/mediacapture-streams\/#h-note-34\">does not align with modern privacy design principles for the Web<\/a>. The data support this: <a href=\"https:\/\/chromestatus.com\/metrics\/feature\/timeline\/popularity\/1119\">7.2% of the web<\/a> calls the <code>enumerateDevices()<\/code> API, greatly exceeding its legitimate use at <a href=\"https:\/\/chromestatus.com\/metrics\/feature\/timeline\/popularity\/1402\">0.2%<\/a>. This highlights significant privacy concerns with 7% likely being web-trackers attempting to fingerprint users! It&#8217;s a whole other blog post.<\/p>\n<p>But what&#8217;s relevant here is a misunderstood <a href=\"https:\/\/www.w3.org\/TR\/audio-output\/#dfn-exposure-decision-algorithm-for-devices-other-than-camera-and-microphone\">microphone loophole<\/a> where devices that act as <em>both speakers and microphone<\/em> must be exposed as both in <code>enumerateDevices()<\/code> upon live microphone access by the website. This allows for headset detection and lets websites promote full duplex audio if they wish. For example, a website might wish to auto-switch to AirPods speakers whenever the user uses the AirPods microphone, and only then. This synchronization puts everything on the same device clock, improving echo.<\/p>\n<p>But this loophole doesn&#8217;t work for speaker selection, because not all speakers have an associated microphone. Users would consider any website-built picker that only shows a subset of their speakers terrible (this is real, we get <a href=\"https:\/\/bugzil.la\/1899771\">bug reports<\/a> about it).<\/p>\n<p>Even if we changed the spec to expose all speakers through the loophole, audience members would still need to grant microphone access even if they never intend to speak, a burdensome requirement.<\/p>\n<p><del>For these reasons we recommend ignoring the microphone loophole for speaker selection. See below what we recommend instead.<\/del><\/p>\n<h2 id=\"other-browsers-today\">How do other browsers manage speakers today?<\/h2>\n<p>How are the other browsers making do without a speaker selection API? The answer is different for each browser.<\/p>\n<p>Safari doesn&#8217;t implement speaker switching (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLMediaElement\/setSinkId#browser_compatibility\"><code>videoElement.setSinkId()<\/code><\/a>) at all. It instead relies on the robust OS-level speaker selection offered by macOS and iOS. This might be great for privacy in Safari, but Firefox needs a solution that works on Windows, Linux, and Android as well.<\/p>\n<p>Chrome <del>is<\/del>was unique in exposing <em>all<\/em> speakers through the microphone loophole violating the spec, and <a href=\"https:\/\/issues.chromium.org\/u\/1\/issues\/331226135\">also interpreting<\/a> <code>allow=\"microphone\"<\/code> as an implicit <code>allow=\"speaker-selection\"<\/code> (likely for lack of support for the latter).<\/p>\n<p>But that seems like a dead-end. Once Chrome fixes <a href=\"https:\/\/crbug.com\/40138537\">crbug 40138537<\/a> to tighten exposure to active use instead of just permission, websites will need to actually turn on the microphone to select speakers.<\/p>\n<p>This is a sad state of affairs for web developers, necessitating a different approach for each browser. Worse, many just copy what they do for microphones since this works in the dominant browser today.<\/p>\n<p>As a result, this puts Firefox in a tough spot as the only browser without working speaker selection on many sites on some platforms, even though it respects user privacy by following the spec. For this reason, we&#8217;re reaching out to web developers. Your assistance can make a significant difference!<\/p>\n<p><em><strong>UPDATE 7\/03\/2025: Mozilla <a href=\"https:\/\/github.com\/w3c\/mediacapture-output\/pull\/150\">relented<\/a>, and Firefox 140+ <a href=\"https:\/\/bugzil.la\/1958963\">exposes all speakers upon microphone access<\/a> for compatibility with other browsers<\/strong>. However, this doesn&#8217;t diminish the usefulness of <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaDevices\/selectAudioOutput\"><code>selectAudioOutput()<\/code><\/a> outside of video conferencing. So we look forward to the other browsers supporting it!<\/em><\/p>\n<h2>Making it work in all browsers<\/h2>\n<p>We&#8217;ll now demonstrate speaker selection working in all browsers. There&#8217;s no shim, but if you&#8217;ve already done this in chromium, then the rest should be relatively simple.<\/p>\n<p>We encourage websites to feature-detect the new API with a fallback to the old API. Like this (HTML):<\/p>\n<pre>\r\nSpeakers:\r\n&lt;span id=\"newapi\"&gt;\r\n  &lt;button id=\"speakers1\"&gt;Default system output...&lt;\/button&gt;\r\n  &lt;button id=\"reset\" hidden&gt;Reset&lt;\/button&gt;\r\n&lt;\/span&gt;\r\n&lt;span id=\"oldapi\" style=\"display: none;\"&gt;\r\n  &lt;select id=\"speakers2\"&gt;\r\n    &lt;option value=\"\"&gt;Default system output&lt;\/option&gt;\r\n  &lt;\/select&gt;\r\n&lt;\/span&gt;\r\n<\/pre>\n<p>Feature detection is then done like this in JS:<\/p>\n<pre>\r\nif (!(\"selectAudioOutput\" in navigator.mediaDevices)) {\r\n  newapi.style.display = \"none\";\r\n  oldapi.style.display = \"inline\";\r\n}\r\n<\/pre>\n<p>We won&#8217;t cover populating the <code>&lt;select&gt;<\/code> from the old API \u2014 it is similar to microphones \u2014 and we covered the new API already. Note, if you want to implement memory like this demo does, have a look at its source for more details.<\/p>\n<p>This results in a demo that works in all browsers:<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/jan-ivar.github.io\/dummy\/gum_picker_output_fallback.html\" allow=\"camera; microphone; speaker-selection\" width=\"100%\" height=\"270px\" frameborder=\"0\"><span style=\"display: inline-block; width: 0px; overflow: hidden; line-height: 0;\" data-mce-type=\"bookmark\" class=\"mce_SELRES_start\">\ufeff<\/span><span style=\"display: inline-block; width: 0px; overflow: hidden; line-height: 0;\" data-mce-type=\"bookmark\" class=\"mce_SELRES_start\">\ufeff<\/span><\/iframe><br \/>\nHit the start button to make it go!<\/p>\n<ul>\n<li>In Firefox, you&#8217;ll enjoy the same great speaker selection experience as above<\/li>\n<li>In Chrome or Edge, you&#8217;ll see speaker choices listed the same way microphones are listed<\/li>\n<li>In Safari&#8230; well, then you&#8217;re on macOS or iOS where this is easily done in the OS instead<\/li>\n<\/ul>\n<p>Please consider applying this to your website. It will help speaker selection work in more browsers. Other vendors will eventually implement this, so you&#8217;ll be future-proofing your website.<\/p>\n<p>I hope you enjoyed this post and found it helpful. I&#8217;d love to hear your feedback or thoughts. If you have comments or questions, you can reach me on <a href=\"https:\/\/twitter.com\/jibrewery\/status\/1807810362483396822\">X<\/a>. See you on the web!<\/p>\n","protected":false},"excerpt":{"rendered":"Today&#8217;s topic is speaker selection. If you&#8217;ve never given it much thought, or consider it straightforward, this post is for you. Let&#8217;s start by testing your general WebRTC knowledge: Pop Quiz: If a website wants to play out of different speakers on your system, what permission must it have? Speaker-selection permission Microphone permission If you [&hellip;]","protected":false},"author":1399,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"coauthors":[301098],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How WebRTC speaker selection works - Advancing WebRTC<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How WebRTC speaker selection works - Advancing WebRTC\" \/>\n<meta property=\"og:description\" content=\"Today&#8217;s topic is speaker selection. If you&#8217;ve never given it much thought, or consider it straightforward, this post is for you. Let&#8217;s start by testing your general WebRTC knowledge: Pop Quiz: If a website wants to play out of different speakers on your system, what permission must it have? Speaker-selection permission Microphone permission If you [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/\" \/>\n<meta property=\"og:site_name\" content=\"Advancing WebRTC\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-01T16:07:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-04T00:50:08+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png\" \/>\n<meta name=\"author\" content=\"Jan-Ivar Bruaroey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan-Ivar Bruaroey\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/\",\"name\":\"How WebRTC speaker selection works - Advancing WebRTC\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png\",\"datePublished\":\"2024-07-01T16:07:58+00:00\",\"dateModified\":\"2025-07-04T00:50:08+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png\",\"contentUrl\":\"https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png\",\"width\":2604,\"height\":1058},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/webrtc\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How WebRTC speaker selection works\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/\",\"name\":\"Advancing WebRTC\",\"description\":\"Committed to moving Firefox and WebRTC forward\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\",\"name\":\"Jan-Ivar Bruaroey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"caption\":\"Jan-Ivar Bruaroey\"},\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How WebRTC speaker selection works - Advancing WebRTC","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/","og_locale":"en_US","og_type":"article","og_title":"How WebRTC speaker selection works - Advancing WebRTC","og_description":"Today&#8217;s topic is speaker selection. If you&#8217;ve never given it much thought, or consider it straightforward, this post is for you. Let&#8217;s start by testing your general WebRTC knowledge: Pop Quiz: If a website wants to play out of different speakers on your system, what permission must it have? Speaker-selection permission Microphone permission If you [&hellip;]","og_url":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/","og_site_name":"Advancing WebRTC","article_published_time":"2024-07-01T16:07:58+00:00","article_modified_time":"2025-07-04T00:50:08+00:00","og_image":[{"url":"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png"}],"author":"Jan-Ivar Bruaroey","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jan-Ivar Bruaroey","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/","url":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/","name":"How WebRTC speaker selection works - Advancing WebRTC","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png","datePublished":"2024-07-01T16:07:58+00:00","dateModified":"2025-07-04T00:50:08+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#primaryimage","url":"https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png","contentUrl":"https:\/\/blog.mozilla.org\/webrtc\/files\/2024\/06\/SpeakersTwoHalves4.png","width":2604,"height":1058},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/webrtc\/how-webrtc-speaker-selection-works\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/webrtc\/"},{"@type":"ListItem","position":2,"name":"How WebRTC speaker selection works"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/webrtc\/#website","url":"https:\/\/blog.mozilla.org\/webrtc\/","name":"Advancing WebRTC","description":"Committed to moving Firefox and WebRTC forward","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd","name":"Jan-Ivar Bruaroey","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f","url":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","caption":"Jan-Ivar Bruaroey"},"url":"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/439"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/users\/1399"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/comments?post=439"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/439\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/media?parent=439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/categories?post=439"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/tags?post=439"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/coauthors?post=439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}