export interface Device { id : string ; name : string ; } export interface Devices { audio : Device [ ] ; selectedAudio : Device | null ; video : Device [ ] ; selectedVideo : Device | null ; } export const stopStream = ( stream ) => { if ( stream === null ) { return ; } stream . getTracks ( ) . forEach ( ( track ) => { track . stop ( ) ; } ) ; } ; const getMediaStream = async ( constraints ) : Promise < MediaStream > => { return navigator . mediaDevices . getUserMedia ( constraints ) ; } ; export const getDevices = async ( ) : Promise < Devices > => { const devices = { audio : [ ] , selectedAudio : null , video : [ ] , selectedVideo : null , } ; ( await navigator . mediaDevices . enumerateDevices ( ) ) . forEach ( ( mediaDevice ) => { if ( mediaDevice . label === "" ) { return ; } const device = { id : mediaDevice . deviceId , name : mediaDevice . label , } ; if ( mediaDevice . kind . toLowerCase ( ) . includes ( "audio" ) ) { devices . audio . push ( device ) ; if ( devices . selectedAudio === null ) { devices . selectedAudio = device ; } } if ( mediaDevice . kind . toLowerCase ( ) . includes ( "video" ) ) { devices . video . push ( device ) ; if ( devices . selectedVideo === null ) { devices . selectedVideo = device ; } } } ) ; return devices ; } ; export const createLocalStream = async ( { audioDeviceId , videoDeviceId , } = { } ) : Promise < MediaStream | null > => { const audio = audioDeviceId !== undefined ? { deviceId : audioDeviceId } : true ; const video = videoDeviceId !== undefined ? { deviceId : videoDeviceId } : true ; try { return await getMediaStream ( { video , audio } ) ; } catch ( err ) { console . error ( err ) ; try { return await getMediaStream ( { audio } ) ; } catch ( err ) { console . error ( err ) ; try { return await getMediaStream ( { video } ) ; } catch ( err ) { console . error ( err ) ; return null ; } } } } ; export const getVideoAudioEnabled = ( stream ) : { audioEnabled : boolean ; videoEnabled : boolean ; } => { if ( stream === null ) { return { audioEnabled : false , videoEnabled : false } ; } const videoTracks = stream . getVideoTracks ( ) ; const audioTracks = stream . getAudioTracks ( ) ; const videoEnabled = videoTracks !== undefined && videoTracks . length > 0 && videoTracks [ 0 ] . enabled ; const audioEnabled = audioTracks !== undefined && audioTracks . length > 0 && audioTracks [ 0 ] . enabled ; return { audioEnabled , videoEnabled } ; } ;