UNPKG

@100mslive/hms-video-store

Version:

@100mslive Core SDK which abstracts the complexities of webRTC while providing a reactive store for data management with a unidirectional data flow

46 lines (43 loc) 2.04 kB
import { HMSPreferredSimulcastLayer, HMSSimulcastLayer, HMSSimulcastLayerDefinition } from '../../interfaces'; export const layerToIntMapping = { [HMSSimulcastLayer.NONE]: -1, [HMSSimulcastLayer.LOW]: 0, [HMSSimulcastLayer.MEDIUM]: 1, [HMSSimulcastLayer.HIGH]: 2, }; const DELTA_THRESHOLD = 0.5; /** * Given the simulcast layers and the current video element dimensions, this function finds the * layer with dimensions closer to the video element dimensions. */ // eslint-disable-next-line complexity export const getClosestLayer = ( simulcastLayers: HMSSimulcastLayerDefinition[], videoElementDimensions: { width: number; height: number }, ): HMSPreferredSimulcastLayer => { let closestLayer: HMSPreferredSimulcastLayer = HMSSimulcastLayer.HIGH; // when both width and height are equal pick height to select a better quality const maxDimension = videoElementDimensions.width > videoElementDimensions.height ? 'width' : 'height'; const layers = [...simulcastLayers].sort((a, b) => layerToIntMapping[a.layer] - layerToIntMapping[b.layer]); const videoDimesion = videoElementDimensions[maxDimension] * (window?.devicePixelRatio || 1); for (let i = 0; i < layers.length; i++) { const { resolution, layer } = layers[i]; const layerDimension = resolution[maxDimension]; // we break here because the layers are already sorted, the next would always be greater if the below condition satisifes if (videoDimesion <= layerDimension) { closestLayer = layer; break; } else { const nextLayer = layers[i + 1]; const nextLayerDimension = nextLayer ? nextLayer.resolution[maxDimension] : Number.POSITIVE_INFINITY; // calculating which layer this dimension is closer to const proximityPercent = (videoDimesion - layerDimension) / (nextLayerDimension - layerDimension); if (proximityPercent < DELTA_THRESHOLD) { // the element's dimension is closer to the current layer closestLayer = layer; break; } } } return closestLayer; };