{"version":3,"sources":["../../src/use-user-media/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useLatest } from '../use-latest'\nimport { usePausable } from '../use-pausable'\nimport { useStableFn } from '../use-stable-fn'\nimport { useSupported } from '../use-supported'\nimport { useUpdateDeepCompareEffect } from '../use-update-deep-compare-effect'\n\nimport type { MutableRefObject } from 'react'\nimport type { Pausable } from '../use-pausable'\n\nexport interface UseUserMediaOptions {\n  /**\n   * Callback when MediaStream is ready\n   */\n  onStart?: (stream: MediaStream) => void\n  /**\n   * Callback when MediaStream is stopped\n   */\n  onStop?(): void\n  /**\n   * Recreate stream when deviceIds or constraints changed\n   *\n   * @defaultValue true\n   */\n  autoSwitch?: boolean\n  /**\n   * MediaStreamConstraints to be applied to the requested MediaStream\n   * If provided, the constraints will override videoDeviceId and audioDeviceId\n   *\n   * @defaultValue {}\n   */\n  constraints?: MediaStreamConstraints\n}\n\nexport interface UseUserMediaReturns extends Pausable {\n  /**\n   * The current MediaStream\n   */\n  stream: MutableRefObject<MediaStream | null>\n  /**\n   * Whether the browser supports getUserMedia\n   */\n  isSupported: boolean\n}\n\n/**\n * A React Hook that helps to manage the user media.\n */\nexport function useUserMedia(options: UseUserMediaOptions = {}): UseUserMediaReturns {\n  const { autoSwitch = true, onStart, onStop, constraints = {} } = options\n\n  const stream = useRef<MediaStream | null>(null)\n  const isSupported = useSupported(() => 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices)\n\n  const clearStream = (triggerStop = true) => {\n    for (const track of stream.current?.getTracks() || []) {\n      track.stop()\n    }\n    triggerStop && latest.current.onStop?.()\n    stream.current = null\n  }\n\n  const pausable = usePausable(\n    false,\n    () => clearStream(),\n    async (ref) => {\n      clearStream(false)\n      ref.current = false\n\n      stream.current = await navigator.mediaDevices.getUserMedia({\n        video: getDeviceOptions('video'),\n        audio: getDeviceOptions('audio'),\n      })\n\n      if (!stream.current) ref.current = true\n\n      latest.current.onStart?.(stream.current)\n    },\n  )\n\n  const latest = useLatest({ onStart, onStop, constraints })\n\n  const getDeviceOptions = useStableFn((type: 'video' | 'audio') => {\n    const { constraints } = latest.current\n    switch (true) {\n      case Boolean(type === 'video' && constraints):\n        return constraints.video || false\n      case Boolean(type === 'audio' && constraints):\n        return constraints.audio || false\n      default:\n        return true\n    }\n  })\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: effect need to re-run when options.constraints changes\n  useUpdateDeepCompareEffect(() => {\n    if (!pausable.isActive() || !autoSwitch) return\n    pausable.resume()\n    return pausable.pause\n  }, [autoSwitch, options.constraints])\n\n  return {\n    stream,\n    isSupported,\n    ...pausable,\n  }\n}\n"],"names":["useUserMedia","options","autoSwitch","onStart","onStop","constraints","stream","useRef","isSupported","useSupported","navigator","mediaDevices","clearStream","triggerStop","latest","current","getTracks","track","stop","pausable","usePausable","ref","getUserMedia","video","getDeviceOptions","audio","useLatest","useStableFn","type","Boolean","useUpdateDeepCompareEffect","isActive","resume","pause"],"mappings":";;;;+BAgDgBA;;;eAAAA;;;qBAhDO;yBACG;2BACE;2BACA;4BACC;0CACc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CpC,SAASA;QAAaC,UAAAA,iEAA+B,CAAC;IAC3D,0BAAiEA,QAAzDC,YAAAA,8CAAa,4BAAMC,UAAsCF,QAAtCE,SAASC,SAA6BH,QAA7BG,+BAA6BH,QAArBI,aAAAA,gDAAc,CAAC;IAE3D,IAAMC,SAASC,IAAAA,aAAM,EAAqB;IAC1C,IAAMC,cAAcC,IAAAA,0BAAY,EAAC;eAAM,kBAAkBC,aAAa,kBAAkBA,UAAUC,YAAY;;IAE9G,IAAMC,cAAc;YAACC,+EAAc;YACbP,iBAGLQ,wBAAAA;YAHV,kCAAA,2BAAA;;YAAL,QAAK,YAAeR,CAAAA,EAAAA,kBAAAA,OAAOS,OAAO,cAAdT,sCAAAA,gBAAgBU,SAAS,OAAM,EAAE,AAAD,sBAA/C,SAAA,6BAAA,QAAA,yBAAA,iCAAkD;gBAAlD,IAAMC,QAAN;gBACHA,MAAMC,IAAI;YACZ;;YAFK;YAAA;;;qBAAA,6BAAA;oBAAA;;;oBAAA;0BAAA;;;;QAGLL,iBAAeC,yBAAAA,CAAAA,kBAAAA,OAAOC,OAAO,EAACX,MAAM,cAArBU,6CAAAA,4BAAAA;QACfR,OAAOS,OAAO,GAAG;IACnB;IAEA,IAAMI,WAAWC,IAAAA,wBAAW,EAC1B,OACA;eAAMR;OACN,SAAOS;;gBAWLP,yBAAAA;;;;wBAVAF,YAAY;wBACZS,IAAIN,OAAO,GAAG;wBAEG;;4BAAML,UAAUC,YAAY,CAACW,YAAY,CAAC;gCACzDC,OAAOC,iBAAiB;gCACxBC,OAAOD,iBAAiB;4BAC1B;;;wBAHAlB,OAAOS,OAAO,GAAG;wBAKjB,IAAI,CAACT,OAAOS,OAAO,EAAEM,IAAIN,OAAO,GAAG;yBAEnCD,0BAAAA,CAAAA,kBAAAA,OAAOC,OAAO,EAACZ,OAAO,cAAtBW,8CAAAA,6BAAAA,iBAAyBR,OAAOS,OAAO;;;;;;QACzC;;IAGF,IAAMD,SAASY,IAAAA,oBAAS,EAAC;QAAEvB,SAAAA;QAASC,QAAAA;QAAQC,aAAAA;IAAY;IAExD,IAAMmB,mBAAmBG,IAAAA,wBAAW,EAAC,SAACC;QACpC,IAAM,AAAEvB,cAAgBS,OAAOC,OAAO,CAA9BV;QACR,OAAQ;YACN,KAAKwB,QAAQD,SAAS,WAAWvB;gBAC/B,OAAOA,YAAYkB,KAAK,IAAI;YAC9B,KAAKM,QAAQD,SAAS,WAAWvB;gBAC/B,OAAOA,YAAYoB,KAAK,IAAI;YAC9B;gBACE,OAAO;QACX;IACF;IAEA,kHAAkH;IAClHK,IAAAA,sDAA0B,EAAC;QACzB,IAAI,CAACX,SAASY,QAAQ,MAAM,CAAC7B,YAAY;QACzCiB,SAASa,MAAM;QACf,OAAOb,SAASc,KAAK;IACvB,GAAG;QAAC/B;QAAYD,QAAQI,WAAW;KAAC;IAEpC,OAAO;QACLC,QAAAA;QACAE,aAAAA;OACGW;AAEP"}