OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-call / client / local / devices.js

81 lines · javascript ref:
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())
  }
}