react-select-media-devices-modal
Version:
A React component library for select media devices
2 lines (1 loc) • 17.6 kB
JavaScript
(function(j,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],e):(j=typeof globalThis<"u"?globalThis:j||self,e(j.ReactSelectMediaDevicesModal={},j.React))})(this,function(j,e){"use strict";const X=()=>{const[g,f]=e.useState([]);return[g,()=>{(async()=>{const a=await navigator.mediaDevices.getUserMedia({audio:!0,video:!0}),m=await navigator.mediaDevices.enumerateDevices();f(m),a.getTracks().forEach(C=>C.stop())})()}]},y=({name:g,value:f,style:p})=>e.createElement("option",{style:p,value:f},g),W=({devices:g,label:f,selectedDevice:p,style:a,onChange:m})=>{if(g===void 0)return e.createElement(e.Fragment,null);const C=E=>{m(E.target.value)},G=`device-select-${f.toLowerCase().replace(/\s/g,"-")}`,L={deviceList:{paddingTop:"8px"},label:{},select:{marginTop:"4px",borderRadius:"4px",height:"32px",display:"flex",alignItems:"center",justifyContent:"right",width:"100%"},deviceItems:{}},O={deviceList:a?{...L.deviceList,...a.deviceList}:L.deviceList,label:a?{...L.label,...a.label}:L.label,select:a?{...L.select,...a.select}:L.select,deviceItems:a?{...L.deviceItems,...a.deviceItems}:L.deviceItems};return e.createElement("div",{style:O.deviceList},e.createElement("label",{style:O.label,htmlFor:G},f),e.createElement("select",{style:O.select,id:G,onChange:C,defaultValue:p==null?void 0:p.deviceId},g.map((E,i)=>e.createElement(y,{style:O.deviceItems,value:E.deviceId,name:E.label,key:i}))))},_=({children:g,disabled:f,style:p,onClick:a})=>{const m={borderRadius:"4px",height:"32px",paddingLeft:"16px",paddingRight:"16px",backgroundColor:"white",borderWidth:"1px"},C=p?{...m,...p}:m;return e.createElement("button",{onClick:a,disabled:f,style:C},g)},R=({isSelectAudioInput:g=!0,isSelectAudioOutput:f=!0,isSelectVideoInput:p=!0,open:a,audioInputDeviceLabel:m="audio input device",audioOutputDeviceLabel:C="audio output device",videoInputDeviceLabel:G="video input device",confirmButtonText:L="Confirm",cancelButtonText:O="Cancel",allowOutsideClick:E=!0,style:i,onDeviceSelected:t,onDeviceSelectCanceled:$})=>{const[B,I]=X(),[x,M]=e.useState(),[F,V]=e.useState(),[k,T]=e.useState(),Q=B.filter(r=>r.kind==="audioinput"),U=B.filter(r=>r.kind==="audiooutput"),A=B.filter(r=>r.kind==="videoinput"),c={background:{position:"fixed",top:0,left:0,width:"100%",height:"100%",backgroundColor:"rgba(0, 0, 0, 0.3)",display:"flex",alignItems:"center",justifyContent:"center"},modal:{background:"white",padding:"16px",borderRadius:"8px",minWidth:"270px"},deviceLists:{display:"grid"},audioInputDeviceList:{},audioOutputDeviceList:{},videoInputDeviceList:{},buttons:{paddingTop:"16px",display:"flex",alignItems:"center",justifyContent:"right"},cancelButton:{},confirmButton:{marginLeft:"4px"}},[l,h]=e.useState({background:i?{...c.background,...i.background}:c.background,modal:i?{...c.modal,...i.modal}:c.modal,deviceLists:i?{...c.deviceLists,...i.deviceLists}:c.deviceLists,audioInputDeviceList:i?{...c.audioInputDeviceList,...i.audioInputDeviceList}:{},audioOutputDeviceList:i?{...c.audioOutputDeviceList,...i.audioOutputDeviceList}:{},videoInputDeviceList:i?{...c.videoInputDeviceList,...i.videoInputDeviceList}:{},buttons:i?{...c.buttons,...i.buttons}:c.buttons,cancelButton:i?{...c.cancelButton,...i.cancelButton}:c.cancelButton,confirmButton:i?{...c.confirmButton,...i.confirmButton}:c.confirmButton});e.useEffect(()=>{h({background:i?{...c.background,...i.background}:c.background,modal:i?{...c.modal,...i.modal}:c.modal,deviceLists:i?{...c.deviceLists,...i.deviceLists}:c.deviceLists,audioInputDeviceList:i?{...c.audioInputDeviceList,...i.audioInputDeviceList}:{},audioOutputDeviceList:i?{...c.audioOutputDeviceList,...i.audioOutputDeviceList}:{},videoInputDeviceList:i?{...c.videoInputDeviceList,...i.videoInputDeviceList}:{},buttons:i?{...c.buttons,...i.buttons}:c.buttons,cancelButton:i?{...c.cancelButton,...i.cancelButton}:c.cancelButton,confirmButton:i?{...c.confirmButton,...i.confirmButton}:c.confirmButton})},[i]),e.useEffect(()=>{a?(navigator.mediaDevices.addEventListener("devicechange",I),I()):navigator.mediaDevices.removeEventListener("devicechange",I)},[a]);const D=()=>{t({audioInput:x!==void 0?x:Q[0],audioOutput:F!==void 0?F:U[0],videoInput:k!==void 0?k:A[0]})},q=()=>{$()},d=r=>{M(Q.find(w=>w.deviceId===r))},v=r=>{V(U.find(w=>w.deviceId===r))},H=r=>{T(A.find(w=>w.deviceId===r))},z=()=>{$()};return a?e.createElement("div",{style:l.background,...E?{onClick:z}:{}},e.createElement("div",{style:l.modal,...E?{onClick:r=>r.stopPropagation()}:{}},e.createElement("div",{style:l.deviceLists},g&&e.createElement(W,{style:l==null?void 0:l.audioInputDeviceList,label:m,devices:Q,selectedDevice:x,onChange:d}),f&&e.createElement(W,{style:l==null?void 0:l.audioOutputDeviceList,label:C,devices:U,selectedDevice:F,onChange:v}),p&&e.createElement(W,{style:l==null?void 0:l.videoInputDeviceList,label:G,devices:A,selectedDevice:k,onChange:H})),e.createElement("div",{style:l.buttons},e.createElement(_,{style:l.cancelButton,onClick:q},O),e.createElement(_,{style:l.confirmButton,onClick:D},L)))):e.createElement(e.Fragment,null)},Z=()=>{const[g,f]=e.useState();return e.useEffect(()=>()=>{g!==void 0&&g.getTracks().forEach(m=>m.stop())},[]),[g,m=>{m.kind!=="audiooutput"&&(async()=>{const C=await navigator.mediaDevices.getUserMedia(m.kind==="audioinput"?{video:!1,audio:{deviceId:m.deviceId}}:{video:{deviceId:m.deviceId},audio:!1});f(C)})()},()=>{g!==void 0&&(g.getTracks().forEach(m=>m.stop()),f(void 0))}]},P=({isSelectAudioInput:g=!0,isSelectAudioOutput:f=!0,isSelectVideoInput:p=!0,open:a,audioInputDeviceLabel:m="audio input device",audioOutputDeviceLabel:C="audio output device",videoInputDeviceLabel:G="video input device",confirmButtonText:L="Confirm",cancelButtonText:O="Cancel",allowOutsideClick:E=!0,style:i,onDeviceSelected:t,onDeviceSelectCanceled:$})=>{const[B,I]=X(),[x,M]=e.useState(),[F,V]=e.useState(),[k,T]=e.useState(),[Q,U,A]=Z(),c=e.useRef(),l=e.useMemo(()=>B.filter(o=>o.kind==="audioinput"),[B]),h=e.useMemo(()=>B.filter(o=>o.kind==="audiooutput"),[B]),D=e.useMemo(()=>B.filter(o=>o.kind==="videoinput"),[B]),q=matchMedia("(max-width: 640px)"),d={background:{position:"fixed",top:0,left:0,width:"100%",height:"100%",backgroundColor:"rgba(0, 0, 0, 0.3)",display:"flex",alignItems:"center",justifyContent:"center"},modal:{background:"white",padding:"16px",borderRadius:"8px"},deviceSelectContainer:q.matches?{display:"grid",gridTemplateColumns:"100%"}:{display:"grid",gridTemplateColumns:"50% 50%"},preview:{minWidth:"270px",minHeight:"180px",maxWidth:"270px",maxHeight:"180px",marginRight:"4px"},previewVideo:{width:"270px",height:"180px"},deviceLists:{display:"grid",minWidth:"270px",marginLeft:"8px"},audioInputDeviceList:{},audioOutputDeviceList:{},videoInputDeviceList:{},buttons:{paddingTop:"16px",display:"flex",alignItems:"center",justifyContent:"right"},cancelButton:{},confirmButton:{marginLeft:"4px"}},[v,H]=e.useState({background:i?{...d.background,...i.background}:d.background,modal:i?{...d.modal,...i.modal}:d.modal,deviceSelectContainer:i?{...d.deviceSelectContainer,...i.deviceSelectContainer}:d.deviceSelectContainer,preview:i?{...d.preview,...i.preview}:d.preview,previewVideo:i?{...d.previewVideo,...i.previewVideo}:d.previewVideo,deviceLists:i?{...d.deviceLists,...i.deviceLists}:d.deviceLists,audioInputDeviceList:i?{...d.audioInputDeviceList,...i.audioInputDeviceList}:d.audioInputDeviceList,audioOutputDeviceList:i?{...d.audioOutputDeviceList,...i.audioOutputDeviceList}:d.audioOutputDeviceList,videoInputDeviceList:i?{...d.videoInputDeviceList,...i.videoInputDeviceList}:d.videoInputDeviceList,buttons:i?{...d.buttons,...i.buttons}:d.buttons,cancelButton:i?{...d.cancelButton,...i.cancelButton}:d.cancelButton,confirmButton:i?{...d.confirmButton,...i.confirmButton}:d.confirmButton});e.useEffect(()=>{H({background:i?{...d.background,...i.background}:d.background,modal:i?{...d.modal,...i.modal}:d.modal,deviceSelectContainer:i?{...d.deviceSelectContainer,...i.deviceSelectContainer}:d.deviceSelectContainer,preview:i?{...d.preview,...i.preview}:d.preview,previewVideo:i?{...d.previewVideo,...i.previewVideo}:d.previewVideo,deviceLists:i?{...d.deviceLists,...i.deviceLists}:d.deviceLists,audioInputDeviceList:i?{...d.audioInputDeviceList,...i.audioInputDeviceList}:d.audioInputDeviceList,audioOutputDeviceList:i?{...d.audioOutputDeviceList,...i.audioOutputDeviceList}:d.audioOutputDeviceList,videoInputDeviceList:i?{...d.videoInputDeviceList,...i.videoInputDeviceList}:d.videoInputDeviceList,buttons:i?{...d.buttons,...i.buttons}:d.buttons,cancelButton:i?{...d.cancelButton,...i.cancelButton}:d.cancelButton,confirmButton:i?{...d.confirmButton,...i.confirmButton}:d.confirmButton})},[i]),e.useEffect(()=>{const o=()=>{q.matches?H({...v,deviceSelectContainer:{display:"grid",gridTemplateColumns:"100%"}}):H({...v,deviceSelectContainer:{display:"grid",gridTemplateColumns:"50% 50%"}})};return q.addEventListener("change",o),()=>{q.removeEventListener("change",o)}},[]),e.useEffect(()=>{a?(navigator.mediaDevices.addEventListener("devicechange",I),I()):navigator.mediaDevices.removeEventListener("devicechange",I)},[a]),e.useEffect(()=>{if(D.length<1)return;const o=D.find(S=>S.deviceId===(k==null?void 0:k.deviceId))??D[0];U(o)},[D]);const z=()=>{A(),t({audioInput:x!==void 0?x:l[0],audioOutput:F!==void 0?F:h[0],videoInput:k!==void 0?k:D[0]})},r=()=>{A(),$()},w=o=>{M(l.find(S=>S.deviceId===o))},n=o=>{V(h.find(S=>S.deviceId===o))},s=o=>{const S=D.find(Y=>Y.deviceId===o);T(S),U(S)};e.useEffect(()=>{const{current:o}=c;o&&(o.srcObject!==null&&o.srcObject instanceof MediaStream&&(o.srcObject.getTracks().forEach(S=>S.stop()),o.pause()),o.srcObject=Q,o.play())},[Q]);const K=()=>{A(),$()};return a?e.createElement("div",{style:v.background,...E?{onClick:K}:{}},e.createElement("div",{style:v.modal,...E?{onClick:o=>o.stopPropagation()}:{}},e.createElement("div",{style:v.deviceSelectContainer},e.createElement("div",{style:v.preview},e.createElement("video",{style:v.previewVideo,ref:c,autoPlay:!0,muted:!0,playsInline:!0})),e.createElement("div",{style:v.deviceLists},g&&e.createElement(W,{style:v.audioInputDeviceList,label:m,devices:l,selectedDevice:x,onChange:w}),f&&e.createElement(W,{style:v==null?void 0:v.audioOutputDeviceList,label:C,devices:h,selectedDevice:F,onChange:n}),p&&e.createElement(W,{style:v==null?void 0:v.videoInputDeviceList,label:G,devices:D,selectedDevice:k,onChange:s}))),e.createElement("div",{style:v.buttons},e.createElement(_,{style:v.cancelButton,onClick:r},O),e.createElement(_,{style:v.confirmButton,onClick:z},L)))):e.createElement(e.Fragment,null)},ee=({isSelectAudioInput:g=!0,isSelectAudioOutput:f=!0,isSelectVideoInput:p=!0,open:a,audioInputDeviceLabel:m="audio input device",audioOutputDeviceLabel:C="audio output device",videoInputDeviceLabel:G="video input device",confirmButtonText:L="Confirm",cancelButtonText:O="Cancel",recordingButtonText:E="Recording",allowOutsideClick:i=!0,style:t,onDeviceSelected:$,onDeviceSelectCanceled:B})=>{const[I,x]=X(),[M,F]=e.useState(),[V,k]=e.useState(),[T,Q]=e.useState(),[U,A,c]=Z(),l=e.useRef(),h=e.useRef(),[D,q]=e.useState(),[d,v]=e.useState(!1),H=e.useMemo(()=>I.filter(u=>u.kind==="audioinput"),[I]),z=e.useMemo(()=>I.filter(u=>u.kind==="audiooutput"),[I]),r=e.useMemo(()=>I.filter(u=>u.kind==="videoinput"),[I]),w=matchMedia("(max-width: 640px)"),n={background:{position:"fixed",top:0,left:0,width:"100%",height:"100%",backgroundColor:"rgba(0, 0, 0, 0.3)",display:"flex",alignItems:"center",justifyContent:"center"},modal:{background:"white",padding:"16px",borderRadius:"8px"},deviceSelectContainer:w.matches?{display:"grid",gridTemplateColumns:"100%"}:{display:"grid",gridTemplateColumns:"50% 50%"},preview:{minWidth:"270px",minHeight:"180px",maxWidth:"270px",marginRight:"4px"},previewVideo:{width:"270px",height:"180px"},previewAudio:{width:"270px"},deviceLists:{display:"grid",minWidth:"270px",marginLeft:"8px"},recordingButtons:{},recordingButton:{},audioInputDeviceList:{},audioOutputDeviceList:{},videoInputDeviceList:{},buttons:{paddingTop:"16px",display:"flex",alignItems:"center",justifyContent:"right"},cancelButton:{},confirmButton:{marginLeft:"4px"}},[s,K]=e.useState({background:t?{...n.background,...t.background}:n.background,modal:t?{...n.modal,...t.modal}:n.modal,deviceSelectContainer:t?{...n.deviceSelectContainer,...t.deviceSelectContainer}:n.deviceSelectContainer,preview:t?{...n.preview,...t.preview}:n.preview,previewVideo:t?{...n.previewVideo,...t.previewVideo}:n.previewVideo,previewAudio:t?{...n.previewAudio,...t.previewAudio}:n.previewAudio,deviceLists:t?{...n.deviceLists,...t.deviceLists}:n.deviceLists,recordingButtons:t?{...n.recordingButtons,...t.recordingButtons}:n.recordingButtons,recordingButton:t?{...n.recordingButton,...t.recordingButton}:n.recordingButton,audioInputDeviceList:t?{...n.audioInputDeviceList,...t.audioInputDeviceList}:n.audioInputDeviceList,audioOutputDeviceList:t?{...n.audioOutputDeviceList,...t.audioOutputDeviceList}:n.audioOutputDeviceList,videoInputDeviceList:t?{...n.videoInputDeviceList,...t.videoInputDeviceList}:n.videoInputDeviceList,buttons:t?{...n.buttons,...t.buttons}:n.buttons,cancelButton:t?{...n.cancelButton,...t.cancelButton}:n.cancelButton,confirmButton:t?{...n.confirmButton,...t.confirmButton}:n.confirmButton});e.useEffect(()=>{K({background:t?{...n.background,...t.background}:n.background,modal:t?{...n.modal,...t.modal}:n.modal,deviceSelectContainer:t?{...n.deviceSelectContainer,...t.deviceSelectContainer}:n.deviceSelectContainer,preview:t?{...n.preview,...t.preview}:n.preview,previewVideo:t?{...n.previewVideo,...t.previewVideo}:n.previewVideo,previewAudio:t?{...n.previewAudio,...t.previewAudio}:n.previewAudio,deviceLists:t?{...n.deviceLists,...t.deviceLists}:n.deviceLists,recordingButtons:t?{...n.recordingButtons,...t.recordingButtons}:n.recordingButtons,recordingButton:t?{...n.recordingButton,...t.recordingButton}:n.recordingButton,audioInputDeviceList:t?{...n.audioInputDeviceList,...t.audioInputDeviceList}:n.audioInputDeviceList,audioOutputDeviceList:t?{...n.audioOutputDeviceList,...t.audioOutputDeviceList}:n.audioOutputDeviceList,videoInputDeviceList:t?{...n.videoInputDeviceList,...t.videoInputDeviceList}:n.videoInputDeviceList,buttons:t?{...n.buttons,...t.buttons}:n.buttons,cancelButton:t?{...n.cancelButton,...t.cancelButton}:n.cancelButton,confirmButton:t?{...n.confirmButton,...t.confirmButton}:n.confirmButton})},[t]),e.useEffect(()=>{const u=()=>{w.matches?K({...s,deviceSelectContainer:{display:"grid",gridTemplateColumns:"100%"}}):K({...s,deviceSelectContainer:{display:"grid",gridTemplateColumns:"50% 50%"}})};return w.addEventListener("change",u),()=>{w.removeEventListener("change",u)}},[]),e.useEffect(()=>{a?(navigator.mediaDevices.addEventListener("devicechange",x),x()):navigator.mediaDevices.removeEventListener("devicechange",x)},[a]),e.useEffect(()=>{if(r.length<1)return;const u=r.find(b=>b.deviceId===(T==null?void 0:T.deviceId))??r[0];A(u)},[r]);const o=()=>{!D||!h||(D.state==="recording"&&(D.removeEventListener("dataavailable",()=>{}),D.removeEventListener("stop",()=>{}),D.stop(),D.stream.getTracks().forEach(u=>u.stop())),h.current.src="",h.current.pause(),c())},S=()=>{o(),$({audioInput:M!==void 0?M:H[0],audioOutput:V!==void 0?V:z[0],videoInput:T!==void 0?T:r[0]})},Y=()=>{o(),B()},ie=u=>{F(H.find(b=>b.deviceId===u))},te=async u=>{k(z.find(b=>b.deviceId===u)),await h.current.setSinkId(u)},ne=u=>{const b=r.find(J=>J.deviceId===u);Q(b),A(b)},de=async()=>{const u=await navigator.mediaDevices.getUserMedia({audio:M&&M.deviceId!==""?{deviceId:M.deviceId}:!0,video:!1});let b=[];const J=new MediaRecorder(u);J.addEventListener("dataavailable",N=>{b.push(N.data)}),J.addEventListener("stop",async N=>{if(v(!1),!h.current)return;const ue=new Blob(b,{type:"audio/ogg; codecs=opus"});b=[];const oe=URL.createObjectURL(ue);h.current.src=oe,V&&V.deviceId!==""&&await h.current.setSinkId(V.deviceId)}),J.start(),q(J),v(!0),setTimeout(()=>{J.stop(),u.getTracks().forEach(N=>N.stop())},5e3)};e.useEffect(()=>{const{current:u}=l;u&&(u.srcObject!==null&&u.srcObject instanceof MediaStream&&(u.srcObject.getTracks().forEach(b=>b.stop()),u.pause()),u.srcObject=U,u.play())},[U]);const ce=()=>{o(),B()};return a?e.createElement("div",{style:s.background,...i?{onClick:ce}:{}},e.createElement("div",{style:s.modal,...i?{onClick:u=>u.stopPropagation()}:{}},e.createElement("div",{style:s.deviceSelectContainer},e.createElement("div",{style:s.preview},e.createElement("video",{style:s.previewVideo,ref:l,autoPlay:!0,muted:!0,playsInline:!0}),e.createElement("audio",{style:s.previewAudio,ref:h,autoPlay:!0,playsInline:!0,controls:!0})),e.createElement("div",{style:s.deviceLists},g&&e.createElement(e.Fragment,null,e.createElement(W,{style:s.audioInputDeviceList,label:m,devices:H,selectedDevice:M,onChange:ie}),e.createElement("div",{style:s.recordingButtons},e.createElement(_,{style:s.recordingButton,onClick:de,disabled:d},E))),f&&e.createElement(W,{style:s==null?void 0:s.audioOutputDeviceList,label:C,devices:z,selectedDevice:V,onChange:te}),p&&e.createElement(W,{style:s==null?void 0:s.videoInputDeviceList,label:G,devices:r,selectedDevice:T,onChange:ne}))),e.createElement("div",{style:s.buttons},e.createElement(_,{style:s.cancelButton,onClick:Y},O),e.createElement(_,{style:s.confirmButton,onClick:S},L)))):e.createElement(e.Fragment,null)};j.SelectMediaDevicesModal=R,j.SelectMediaDevicesPreviewModal=P,j.SelectMediaDevicesRecordingModal=ee,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});