const { Readable: e } = require("streamx"),
i = require("debounceify"),
t = require("safety-catch")
function s(e) {
const i = [],
t = [],
s = [],
a = {},
o = new Map(),
r = c(e)
return (
e.forEach(({ kind: e, label: c, deviceId: n, groupId: u }) => {
if (!n || !c || "default" === n) return
const d = `${c}|${e}`,
v = o.get(d) || 0
o.set(d, v + 1)
const h = `${d}|${o.get(d)}`,
p = { deviceStaticId: h, deviceId: n, default: r[e] === u, kind: e, label: c }
switch (((a[h] = p), e)) {
case "videoinput":
t.push(p)
break
case "audioinput":
i.push(p)
break
case "audiooutput":
s.push(p)
}
}),
{ audio: i.sort(n), audioOutput: s.sort(n), video: t.sort(n), devicesMap: a }
)
}
function c(e) {
return e.reduce(
(e, { deviceId: i, kind: t, groupId: s }) => ("default" === i && (e[t] = s), e),
{},
)
}
function n(e) {
return e.default ? -1 : 1
}
module.exports = class {
constructor() {
;((this._deviceSubscriptions = []),
(this._ondevicechange = i(this._onDeviceChange.bind(this))),
navigator.mediaDevices.addEventListener("devicechange", this._ondevicechange))
}
close() {
navigator.mediaDevices.removeEventListener("devicechange", this._ondevicechange)
}
async _onDeviceChange() {
try {
const e = await this.getDevices()
for (const i of this._deviceSubscriptions) i.push(e)
} catch (e) {
t(e)
}
}
subscribeDevices() {
const i = this,
t = new e({
open(e) {
i.getDevices().then(
(i) => {
;(this.push(i), e(null))
},
(i) => e(i),
)
},
destroy(e) {
const s = i._deviceSubscriptions.indexOf(t)
;(-1 !== s && i._deviceSubscriptions.splice(s, 1), e(null))
},
})
return (this._deviceSubscriptions.push(t), t)
}
async getDevices() {
return s(await navigator.mediaDevices.enumerateDevices())
}
}