99 lines
2.6 KiB
JavaScript
99 lines
2.6 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
import {
|
|
VIDEO_QUALITY_HIGH,
|
|
VIDEO_QUALITY_LOW,
|
|
VIDEO_QUALITY_BANDWIDTH_SAVER,
|
|
} from '../constants';
|
|
|
|
export const NETWORK_STATE_GOOD = 'good';
|
|
export const NETWORK_STATE_LOW = 'low';
|
|
export const NETWORK_STATE_VERY_LOW = 'very-low';
|
|
const STANDARD_HIGH_BITRATE_CAP = 980;
|
|
const STANDARD_LOW_BITRATE_CAP = 300;
|
|
|
|
export const useNetworkState = (
|
|
callObject = null,
|
|
quality = VIDEO_QUALITY_HIGH
|
|
) => {
|
|
const [threshold, setThreshold] = useState(NETWORK_STATE_GOOD);
|
|
|
|
const setQuality = useCallback(
|
|
(q) => {
|
|
if (!callObject) return;
|
|
|
|
const peers = Object.keys(callObject.participants()).length - 1;
|
|
const isSFU = callObject.getNetworkTopology().topology === 'sfu';
|
|
|
|
const lowKbs = isSFU
|
|
? STANDARD_LOW_BITRATE_CAP
|
|
: STANDARD_LOW_BITRATE_CAP / Math.max(1, peers);
|
|
|
|
switch (q) {
|
|
case VIDEO_QUALITY_HIGH:
|
|
callObject.setBandwidth({ kbs: STANDARD_HIGH_BITRATE_CAP });
|
|
break;
|
|
case VIDEO_QUALITY_LOW:
|
|
callObject.setBandwidth({
|
|
kbs: lowKbs,
|
|
});
|
|
break;
|
|
case VIDEO_QUALITY_BANDWIDTH_SAVER:
|
|
callObject.setLocalVideo(false);
|
|
callObject.setBandwidth({
|
|
kbs: lowKbs,
|
|
});
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
[callObject]
|
|
);
|
|
|
|
const handleNetworkQualityChange = useCallback(
|
|
(ev) => {
|
|
if (ev.threshold === threshold) return;
|
|
|
|
switch (ev.threshold) {
|
|
case NETWORK_STATE_VERY_LOW:
|
|
setQuality(VIDEO_QUALITY_BANDWIDTH_SAVER);
|
|
setThreshold(NETWORK_STATE_VERY_LOW);
|
|
break;
|
|
case NETWORK_STATE_LOW:
|
|
setQuality(
|
|
quality === VIDEO_QUALITY_BANDWIDTH_SAVER
|
|
? quality
|
|
: NETWORK_STATE_LOW
|
|
);
|
|
setThreshold(NETWORK_STATE_LOW);
|
|
break;
|
|
case NETWORK_STATE_GOOD:
|
|
setQuality(
|
|
[VIDEO_QUALITY_BANDWIDTH_SAVER, VIDEO_QUALITY_LOW].includes(quality)
|
|
? quality
|
|
: VIDEO_QUALITY_HIGH
|
|
);
|
|
setThreshold(NETWORK_STATE_GOOD);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
[setQuality, threshold, quality]
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (!callObject) return false;
|
|
callObject.on('network-quality-change', handleNetworkQualityChange);
|
|
return () =>
|
|
callObject.off('network-quality-change', handleNetworkQualityChange);
|
|
}, [callObject, handleNetworkQualityChange]);
|
|
|
|
useEffect(() => {
|
|
setQuality(quality);
|
|
}, [quality, setQuality]);
|
|
|
|
return threshold;
|
|
};
|