import { useEffect, useState } from "react"; import { MdGraphicEq, MdSignalWifi4Bar, MdError } from "react-icons/md"; import { LuActivity, LuClock, LuHardDrive, LuSettings } from "react-icons/lu"; import { cx } from "@/cva.config"; import api from "@/api"; interface AudioMetrics { frames_received: number; frames_dropped: number; bytes_processed: number; last_frame_time: string; connection_drops: number; average_latency: string; } interface AudioConfig { Quality: number; Bitrate: number; SampleRate: number; Channels: number; FrameSize: string; } const qualityLabels = { 0: "Low", 1: "Medium", 2: "High", 3: "Ultra" }; export default function AudioMetricsDashboard() { const [metrics, setMetrics] = useState(null); const [config, setConfig] = useState(null); const [isConnected, setIsConnected] = useState(false); const [lastUpdate, setLastUpdate] = useState(new Date()); useEffect(() => { loadAudioData(); // Refresh every 1 second for real-time metrics const interval = setInterval(loadAudioData, 1000); return () => clearInterval(interval); }, []); const loadAudioData = async () => { try { // Load metrics const metricsResp = await api.GET("/audio/metrics"); if (metricsResp.ok) { const metricsData = await metricsResp.json(); setMetrics(metricsData); // Consider connected if API call succeeds, regardless of frame count setIsConnected(true); setLastUpdate(new Date()); } else { setIsConnected(false); } // Load config const configResp = await api.GET("/audio/quality"); if (configResp.ok) { const configData = await configResp.json(); setConfig(configData.current); } } catch (error) { console.error("Failed to load audio data:", error); setIsConnected(false); } }; const formatBytes = (bytes: number) => { if (bytes === 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; }; const formatNumber = (num: number) => { return new Intl.NumberFormat().format(num); }; const getDropRate = () => { if (!metrics || metrics.frames_received === 0) return 0; return ((metrics.frames_dropped / metrics.frames_received) * 100); }; const getQualityColor = (quality: number) => { switch (quality) { case 0: return "text-yellow-600 dark:text-yellow-400"; case 1: return "text-blue-600 dark:text-blue-400"; case 2: return "text-green-600 dark:text-green-400"; case 3: return "text-purple-600 dark:text-purple-400"; default: return "text-slate-600 dark:text-slate-400"; } }; return (
{/* Header */}

Audio Metrics

{isConnected ? "Active" : "Inactive"}
{/* Current Configuration */} {config && (
Current Configuration
Quality: {qualityLabels[config.Quality as keyof typeof qualityLabels]}
Bitrate: {config.Bitrate}kbps
Sample Rate: {config.SampleRate}Hz
Channels: {config.Channels}
)} {/* Performance Metrics */} {metrics && (
{/* Frames */}
Frame Statistics
{formatNumber(metrics.frames_received)}
Frames Received
0 ? "text-red-600 dark:text-red-400" : "text-green-600 dark:text-green-400" )}> {formatNumber(metrics.frames_dropped)}
Frames Dropped
{/* Drop Rate */}
Drop Rate 5 ? "text-red-600 dark:text-red-400" : getDropRate() > 1 ? "text-yellow-600 dark:text-yellow-400" : "text-green-600 dark:text-green-400" )}> {getDropRate().toFixed(2)}%
5 ? "bg-red-500" : getDropRate() > 1 ? "bg-yellow-500" : "bg-green-500" )} style={{ width: `${Math.min(getDropRate(), 100)}%` }} />
{/* Data Transfer */}
Data Transfer
{formatBytes(metrics.bytes_processed)}
Total Processed
{/* Connection Health */}
Connection Health
Connection Drops: 0 ? "text-red-600 dark:text-red-400" : "text-green-600 dark:text-green-400" )}> {formatNumber(metrics.connection_drops)}
{metrics.average_latency && (
Avg Latency: {metrics.average_latency}
)}
)} {/* Last Update */}
Last updated: {lastUpdate.toLocaleTimeString()}
{/* No Data State */} {!metrics && (

No Audio Data

Audio metrics will appear when audio streaming is active.

)}
); }