browser compatibility
1 TopicTeams - Actively hiding some audio devices?
Hi, Apologies in advance, but this one may be long... Somewhere around September 2019, the Teams's webapp's built-in chat audio device behaviour changed (I believe it was around the same time it finally became possible to adjust (some) audio settings before joining a call/meeting). At this time, Teams appeared to stop respecting my system 'default microphone' setting, and the list of microphone drop-downs only shows a subset of the available audio devices on my machine (crucially not the ones I am interested in!). To be extra clear, I am only interested in the WebApp (not any of the electron-ified desktop apps), and have always been running it in Chrom(ium) on Linux (currently ver 87.0.4280.88) with audio provided via ALSA, but the exact version of Chrom(ium) seems to be irrelevant, as I will show later. Notably, Teams is the only web-based tool that fails to offer all my audio devices, other webapps (e.g. mictests.com, webex, zoom, etc.) which also use the standard WebAudio APIs provide a full device list and therefore 'just work'. It took a few months, but I finally took the time to start actively hunting through the Teams (de-minified) JS looking for clues, guessing that somewhere at the bottom of the stack it would be using the WebRTC and WebAudio standard libraries. Delving in to the skype-calling-pluginless.bundle-X.js filex (oh look, Teams is really just another wrapper on top of skype (or is it SfB?)), there were are a few areas which seemed to confirm my suspicions that Teams must have some kind of custom handling on top of the browser-provided API which is causing it to be misled. In this first snippet, we see custom handling whereby Teams attempts to ignore the user-set default microphone if it decides it is too "synthetic": }, t.prototype.updateActiveDevices = function(e) { if (e.microphone && e.microphone.isMarkedDefault) { var t = this.lists.get(s.default.MEDIA_DEVICE.microphone), n = t.findIndex(function(e) { return e.isSystemDefault }); - 1 !== n && t[n] !== e.microphone.device ? (this.logger.safe.info("Removing synthetic default microphone"), this.lists.set(s.default.MEDIA_DEVICE.microphone, t.splice(n, 1))) : e.microphone.device.isSystemDefault = !0 } It also turns out Teams has a hard-coded whitelist and blacklist of 'approved' names of audio devices, which appears to be why many of mine are removed from the list of devices offered in the UI: devices: { blacklist: { microphone: "stereo mix \\(", camera: "ir camera", speaker: "" }, compositeAudioDevices: !0, compositeLabelMatchingThreshold: .5, piiSafeWords: ["virtual", "usb", "test", "default", "remote audio", "built-in", "s/pdif", "digital", "dock", "thunderbolt\\d*", "line( in| out)?", "analog", "high definition", "smartaudio", "macbook", "airpod", "stereo", "hands-free", "display", "dp", "displayport", "hdmi", "cable", "nvidia", "amd", "citrix hdx", "vmware", "integrated", "panoramic", "facetime", "front", "rear", "desktop", "capture", "cam", "snap camera", "obs-camera", "vb-audio", "vaio", "manycam"] }, Here's the section handling the blacklisting and also looking for anything flagged as 'communications' instead: t.compilePrimitiveDeviceList = function(e, t, n, o, d) { var u, p; void 0 === d && (d = { str: "" }), d.str += "|input(" + t.length + ")"; var f = [], h = [o.config.devices.blacklist[e], o.defaultConfig.devices.blacklist[e]]; try { for (var g = r(h), m = g.next(); !m.done && "break" !== function(e) { try { var n = new RegExp(e, "i"); return f = t.filter(function(t) { return e && t.label.match(n) ? (d.str += "|-blacklisted(" + t.label + ")", !1) : t.deviceId !== c.default.MEDIA_DEVICE.communicationsId || (d.str += "|-communications", !1) }), "break" } catch (n) { d.str += "|filterError('" + e + "', " + s.stringifyObject(n) + ")", f = t } }(m.value); m = g.next()); } catch (e) { u = { error: e } } finally { try { m && !m.done && (p = g.return) && p.call(g) } finally { if (u) throw u.error } } if (f.length) { var S = i(n, f, d); if (S && (S.isSystemDefault = !0, d.str += "|default(" + a.scrubMriOrOmit(S.guid) + ")", f.splice(f.indexOf(S), 1), f.unshift(S)), f.length > 1 && (f = f.filter(function(e) { return e.deviceId !== c.default.MEDIA_DEVICE.defaultId || (d.str += "|-defaultId", !1) })), e === c.default.MEDIA_DEVICE.camera || S || (d.str += "|+syntheticDefault", f.unshift(l.createDefaultDevice(e))), n.forEach(function(e) { var t = f.find(function(t) { return t.guid === e.guid }); t && !t.label && e.label && (d.str += "|migrateLabel(" + a.scrubMriOrOmit(t.guid) + ")", t.label = e.label) }), e === c.default.MEDIA_DEVICE.speaker) { var E = f.filter(function(e) { return "" === e.label }); E.length > 1 && E.length === f.length && (f = S ? [S] : [f[0]], d.str += "|-filteredEmptyLabels(" + E.length + ")") } } return f } }, function(e, t, n) { Does anyone know why Teams appears to have decided to know better than the end-user about which audio devices to use (and hence gets it completely wrong on any machines that don't happen to meet the hard-coded values because they use a rarer type of 'sound card')? Where do I go to request all of this code is removed from Teams and it instead simply uses the WebAudio API response to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices as intended by W3, leaving interfacing with hardware up to the user agent (browser)? Thanks3.1KViews1like0Comments