Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v0.7.20 88 lines 2.4 kB view raw
1import { useEffect, useRef, useState } from "react"; 2import { useLivestreamStore } from "../livestream-store"; 3 4export type ConnectionQuality = "good" | "degraded" | "poor"; 5 6function getLiveConnectionQuality( 7 timeBetweenSegments: number | null, 8 range: number | null, 9 numOfSegments: number = 1, 10): ConnectionQuality { 11 if (timeBetweenSegments === null || range === null) return "poor"; 12 13 if (timeBetweenSegments <= 1500 && range <= (1500 * 60) / numOfSegments) { 14 return "good"; 15 } 16 if (timeBetweenSegments <= 3000 && range <= (3000 * 60) / numOfSegments) { 17 return "degraded"; 18 } 19 return "poor"; 20} 21 22export function useSegmentTiming() { 23 const latestSegment = useLivestreamStore((x) => x.segment); 24 const [segmentDeltas, setSegmentDeltas] = useState<number[]>([]); 25 const prevSegmentRef = useRef<any>(); 26 const prevTimestampRef = useRef<number | null>(null); 27 28 // Dummy state to force update every second 29 const [, setNow] = useState(Date.now()); 30 31 useEffect(() => { 32 const interval = setInterval(() => { 33 setNow(Date.now()); 34 }, 1000); 35 return () => clearInterval(interval); 36 }, []); 37 38 useEffect(() => { 39 if (latestSegment && prevSegmentRef.current !== latestSegment) { 40 const now = Date.now(); 41 if (prevTimestampRef.current !== null) { 42 const delta = now - prevTimestampRef.current; 43 // Only store the last 25 deltas 44 setSegmentDeltas((prev) => [...prev, delta].slice(-25)); 45 } 46 prevTimestampRef.current = now; 47 prevSegmentRef.current = latestSegment; 48 } 49 }, [latestSegment]); 50 51 // The most recent time between segments 52 const timeBetweenSegments = 53 segmentDeltas.length > 0 54 ? segmentDeltas[segmentDeltas.length - 1] 55 : prevTimestampRef.current 56 ? Date.now() - prevTimestampRef.current 57 : null; 58 59 // Calculate mean and range of deltas 60 const mean = 61 segmentDeltas.length > 0 62 ? Math.round( 63 segmentDeltas.reduce((acc, curr) => acc + curr, 0) / 64 segmentDeltas.length, 65 ) 66 : null; 67 68 const range = 69 segmentDeltas.length > 0 70 ? Math.max(...segmentDeltas) - Math.min(...segmentDeltas) 71 : null; 72 73 let to_ret = { 74 segmentDeltas, 75 timeBetweenSegments, 76 mean, 77 range, 78 connectionQuality: "poor", 79 }; 80 81 to_ret.connectionQuality = getLiveConnectionQuality( 82 timeBetweenSegments, 83 range, 84 segmentDeltas.length, 85 ); 86 87 return to_ret; 88}