import React, { useRef } from 'react'; import { HMSTrackID, HMSTrackStats, selectHMSStats, } from '@100mslive/hms-video-store'; import { useHMSStatsStore } from '../../../hooks/HMSRoomProvider'; import { useHMSTheme } from '../../../hooks/HMSThemeProvider'; import { formatBytes, isPresent, isMobileDevice } from '../../../utils'; export interface VideoTileStatsProps { compact?: boolean; videoTrackID?: HMSTrackID; audioTrackID?: HMSTrackID; } const StatsRow = ({ label = '', trackType = '', value = '', compact = false, }) => { const { tw } = useHMSTheme(); if (trackType) { label = `${label} (${compact ? trackType[0] : trackType})`; } return ( {label} {value} ); }; const PacketsLostRow = ({ stats, compact, trackType, }: { stats?: HMSTrackStats; compact?: boolean; trackType: 'Video' | 'Audio'; }) => { const packetsLostRate = (stats?.packetsLostRate ? stats.packetsLostRate.toFixed(2) : stats?.packetsLostRate) + '/s'; return isPresent(stats?.packetsLost) && isPresent(stats?.packetsLostRate) ? ( ) : null; }; const ResolutionRow = ({ stats, compact = false, }: { stats: HMSTrackStats; compact?: boolean; }) => { if (!stats?.frameWidth) { return null; } const resolutionWithFPS = `${stats?.frameWidth}x${stats?.frameHeight}@${stats?.framesPerSecond}`; return compact ? ( <> ) : ( ); }; export function VideoTileStats({ videoTrackID, audioTrackID, compact = false, }: VideoTileStatsProps) { const { tw } = useHMSTheme(); const rootRef = useRef(null); const containerStyle: React.CSSProperties = { backgroundColor: 'rgba(0,0,0,0.75)', zIndex: 15, }; compact = compact || isMobileDevice(); if (compact) { const parentHeight = rootRef.current?.parentElement?.clientHeight || 0; const parentWidth = rootRef.current?.parentElement?.clientWidth || 0; containerStyle.width = `calc(${parentWidth}px - 1rem)`; containerStyle.maxHeight = parentHeight * 0.75; containerStyle.overflowY = 'auto'; } const audioTrackStats = useHMSStatsStore( selectHMSStats.trackStatsByID(audioTrackID), ); const videoTrackStats = useHMSStatsStore( selectHMSStats.trackStatsByID(videoTrackID), ); // Viewer role - no stats to show if (!(audioTrackStats || videoTrackStats)) { return null; } return (
{videoTrackStats && ( )} {isPresent(videoTrackStats?.bitrate) && ( )} {isPresent(audioTrackStats?.bitrate) && ( )} {isPresent(videoTrackStats?.jitter) && ( )} {isPresent(audioTrackStats?.jitter) && ( )}
); }