UNPKG

infobip-rtc

Version:

Infobip RTC JavaScript SDK - Infobip WebRTC API Implementation

201 lines 8.07 kB
import "webrtc-adapter"; import { CameraOrientation } from "../call/options/CameraOrientation"; import { findIndex, uniqBy } from 'lodash-es'; import { VideoOptionsUtil } from "../util/VideoOptionsUtil"; export class DefaultDevice { constructor(logger) { this.logger = logger; this.deviceKindNames = { "audioinput": "Microphone", "audiooutput": "Speaker", "videoinput": "Camera" }; this.getMicrophoneDefaults = () => ({ noiseSuppression: true, echoCancellation: true }); this.getCameraDefaults = (hdResolution = false, cameraVideoFrameRate) => ({ width: hdResolution ? 1280 : 640, height: hdResolution ? 720 : 480, frameRate: VideoOptionsUtil.limitFps(cameraVideoFrameRate) || DefaultDevice.CAMERA_VIDEO_FPS_DEFAULT }); this.getScreenShareDefaults = (screenShareFrameRate) => ({ width: { max: 1920 }, height: { max: 1080 }, frameRate: VideoOptionsUtil.limitFps(screenShareFrameRate) || DefaultDevice.SCREEN_SHARE_FPS_DEFAULT, cursor: "always" }); } getAudioInputDevices() { return this.getDevices("audioinput") .then(devices => this.updateDevices(devices)); } getAudioOutputDevices() { return this.getDevices("audiooutput") .then(devices => this.updateDevices(devices)); } getVideoInputDevices() { return this.getDevices("videoinput") .then(devices => this.updateDevices(devices)); } setAudioInputDevice(id) { this.audioInputDevice = { deviceId: id, kind: "audioinput" }; } unsetAudioInputDevice() { this.audioInputDevice = null; } getAudioInputDevice() { return this.audioInputDevice?.deviceId; } audioInputDeviceShouldChange() { return this.getAudioInputDevices() .then(devices => { return devices.findIndex(device => device.deviceId === this.audioInputDevice?.deviceId) === -1 && devices.length > 0; }) .catch(() => { return false; }); } setVideoInputDevice(id) { this.videoInputDevice = { deviceId: id, kind: "videoinput" }; } unsetVideoInputDevice() { this.videoInputDevice = null; } getVideoInputDevice() { return this.videoInputDevice?.deviceId; } getCameraOrientation() { return this.cameraOrientation; } async getLocalStream(audio = true, video = false, cameraOrientation = CameraOrientation.FRONT, hdResolution = false, useExactDevice = true, cameraVideoFrameRate) { let mediaConstraints = {}; let devices = []; try { this.cameraOrientation = cameraOrientation; if (audio) { if (this.audioInputDevice) { const audioDevices = await this.getDevices("audioinput"); devices.push(...audioDevices); const audioDeviceConstraints = this.getDeviceConstraint(audioDevices, this.audioInputDevice); mediaConstraints.audio = this.getAudioConstraints(audioDeviceConstraints); } else { mediaConstraints.audio = this.getAudioConstraints(null); } } if (video) { if (this.videoInputDevice) { const videoDevices = await this.getDevices("videoinput"); devices.push(...videoDevices); const videoDeviceConstraints = this.getDeviceConstraint(videoDevices, this.videoInputDevice, useExactDevice); mediaConstraints.video = this.getVideoConstraints(videoDeviceConstraints, cameraOrientation, hdResolution, cameraVideoFrameRate); } else { mediaConstraints.video = this.getVideoConstraints(null, cameraOrientation, hdResolution, cameraVideoFrameRate); } } return await navigator.mediaDevices.getUserMedia(mediaConstraints); } catch (error) { if (error) { this.logger.error(`Failed to request device audio=${audio} video=${video} with constraints ${mediaConstraints && JSON.stringify(mediaConstraints)} (${devices && JSON.stringify(devices)}) - ${error}`); } throw error; } } getDisplayMedia(displayOptions, screenShareFrameRate) { const constraints = { video: this.getScreenShareDefaults(screenShareFrameRate), ...(displayOptions && { monitorTypeSurfaces: "include" }), }; if (displayOptions) { constraints.video.displaySurface = displayOptions.allowedDisplayOptions[0]; } if (displayOptions && !displayOptions.allowedDisplayOptions.includes("monitor")) { constraints.monitorTypeSurfaces = "exclude"; } return navigator.mediaDevices.getDisplayMedia?.(constraints) ?? Promise.reject("Screen share is not supported."); } getAudioConstraints(deviceId = null) { return { ...this.getMicrophoneDefaults(), deviceId }; } getVideoConstraints(deviceId = null, cameraOrientation = CameraOrientation.FRONT, hdResolution = false, cameraVideoFrameRate) { return { ...this.getCameraDefaults(hdResolution, cameraVideoFrameRate), facingMode: cameraOrientation, deviceId }; } getDeviceConstraint(devices, inputDevice, useExactDevice = true) { if (!inputDevice) return null; let videoInputDeviceExists = findIndex(devices, { kind: inputDevice.kind, deviceId: inputDevice.deviceId }) !== -1; return videoInputDeviceExists && useExactDevice ? { exact: inputDevice.deviceId } : null; } async getDevices(deviceKind = null) { const mediaDevices = await this.enumerateDevices(deviceKind); if (mediaDevices.length === 0) { return []; } if (mediaDevices[0].label) { return this.filterDevices(mediaDevices, deviceKind); } else { return this.getUserMediaDevices(deviceKind); } } filterDevices(mediaDeviceInfos, deviceKind) { if (deviceKind) { let devices = mediaDeviceInfos.filter(device => device.kind === deviceKind); return uniqBy(devices, 'deviceId'); } return uniqBy(mediaDeviceInfos, 'deviceId'); } async getUserMediaDevices(deviceKind) { let constraints = deviceKind === 'videoinput' ? { video: true } : { audio: true }; const stream = await navigator.mediaDevices.getUserMedia(constraints); this.stopTracks(stream); return await this.enumerateDevices(deviceKind); } async enumerateDevices(deviceKind) { const mediaDevices = await navigator.mediaDevices.enumerateDevices(); return this.filterDevices(mediaDevices, deviceKind); } stopTracks(stream) { stream.getTracks().forEach((track) => track.stop()); } updateDevices(devices) { return devices.map((device, index) => { return this.generateCustomMediaDeviceInfo(device, index + 1); }); } generateCustomMediaDeviceInfo(mediaDeviceInfo, index) { let deviceKindName = this.deviceKindNames[mediaDeviceInfo.kind]; let customMediaDeviceInfo = mediaDeviceInfo.toJSON(); if (!mediaDeviceInfo.label) { customMediaDeviceInfo.label = mediaDeviceInfo.deviceId === "default" ? `Default ${deviceKindName}` : `${deviceKindName} ${index}`; } return customMediaDeviceInfo; } } DefaultDevice.CAMERA_VIDEO_FPS_DEFAULT = 24; DefaultDevice.SCREEN_SHARE_FPS_DEFAULT = 8; //# sourceMappingURL=DefaultDevice.js.map