diff --git a/client/src/components/quality-indicator.tsx b/client/src/components/quality-indicator.tsx index a05834d..c49d033 100644 --- a/client/src/components/quality-indicator.tsx +++ b/client/src/components/quality-indicator.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { Signal } from "lucide-react"; +import { Signal, Activity, Wifi } from "lucide-react"; interface QualityIndicatorProps { hlsInstance: any; @@ -8,8 +8,11 @@ interface QualityIndicatorProps { export default function QualityIndicator({ hlsInstance, className = "" }: QualityIndicatorProps) { const [currentQuality, setCurrentQuality] = useState(""); + const [currentBitrate, setCurrentBitrate] = useState(0); const [networkType, setNetworkType] = useState(""); const [bufferHealth, setBufferHealth] = useState<"good" | "medium" | "poor">("good"); + const [downloadSpeed, setDownloadSpeed] = useState(0); + const [isBuffering, setIsBuffering] = useState(false); useEffect(() => { if (!hlsInstance) return; @@ -18,6 +21,8 @@ export default function QualityIndicator({ hlsInstance, className = "" }: Qualit const handleLevelSwitch = (event: any, data: any) => { const level = hlsInstance.levels[data.level]; setCurrentQuality(`${level.height}p`); + setCurrentBitrate(Math.round(level.bitrate / 1000)); // Convert to kbps + console.log(`Preklopil na: ${level.height}p @ ${Math.round(level.bitrate/1000)}kbps`); }; // Monitor buffer health @@ -35,8 +40,29 @@ export default function QualityIndicator({ hlsInstance, className = "" }: Qualit } }; + // Monitor loading progress and speed + const handleFragLoaded = (event: any, data: any) => { + const stats = data.stats; + if (stats) { + const speed = (stats.total * 8) / (stats.loading.end - stats.loading.start); // bits per ms + const speedKbps = Math.round(speed); // Convert to kbps + setDownloadSpeed(speedKbps); + console.log(`Download hitrost: ${speedKbps} kbps`); + } + }; + + const handleWaiting = () => setIsBuffering(true); + const handlePlaying = () => setIsBuffering(false); + hlsInstance.on('hlsLevelSwitched', handleLevelSwitch); hlsInstance.on('hlsBufferAppending', handleBufferAppending); + hlsInstance.on('hlsFragLoaded', handleFragLoaded); + + const video = hlsInstance.media; + if (video) { + video.addEventListener('waiting', handleWaiting); + video.addEventListener('playing', handlePlaying); + } // Detect network connection const connection = (navigator as any).connection; @@ -58,6 +84,11 @@ export default function QualityIndicator({ hlsInstance, className = "" }: Qualit if (hlsInstance) { hlsInstance.off('hlsLevelSwitched', handleLevelSwitch); hlsInstance.off('hlsBufferAppending', handleBufferAppending); + hlsInstance.off('hlsFragLoaded', handleFragLoaded); + } + if (video) { + video.removeEventListener('waiting', handleWaiting); + video.removeEventListener('playing', handlePlaying); } }; }, [hlsInstance]); @@ -74,11 +105,37 @@ export default function QualityIndicator({ hlsInstance, className = "" }: Qualit if (!currentQuality) return null; return ( -
- - {currentQuality} +
+ {/* Quality and Signal */} +
+ + {currentQuality} + {isBuffering && ( + + )} +
+ + {/* Bitrate */} + {currentBitrate > 0 && ( +
+ Bitrate: + {currentBitrate} kbps +
+ )} + + {/* Download Speed */} + {downloadSpeed > 0 && ( +
+ + {downloadSpeed} kbps +
+ )} + + {/* Network Type */} {networkType && ( - ({networkType}) +
+ Omrežje: {networkType} +
)}
); diff --git a/client/src/components/video-modal.tsx b/client/src/components/video-modal.tsx index 9393d1d..0aa32bd 100644 --- a/client/src/components/video-modal.tsx +++ b/client/src/components/video-modal.tsx @@ -132,25 +132,43 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps) console.log('HLS manifest loaded - Available qualities:', data.levels.map(l => `${l.height}p @ ${Math.round(l.bitrate/1000)}kbps`)); + // Log bitrate analysis + console.log('BITRATE ANALIZA:'); + data.levels.forEach((level, index) => { + console.log(`Nivo ${index}: ${level.width}x${level.height} @ ${Math.round(level.bitrate/1000)}kbps`); + }); + // Set initial quality based on connection const connection = (navigator as any).connection; if (connection) { const effectiveType = connection.effectiveType; - console.log('Network type detected:', effectiveType); + const downlink = connection.downlink; // Mbps + console.log(`Omrežje: ${effectiveType}, hitrost: ${downlink} Mbps`); - // Adjust starting level based on network - if (effectiveType === 'slow-2g' || effectiveType === '2g') { - hls.startLevel = 0; // Start with lowest quality - } else if (effectiveType === '3g') { + // More aggressive quality selection for slow connections + if (effectiveType === 'slow-2g' || effectiveType === '2g' || downlink < 1) { + hls.startLevel = 0; // Lowest quality + console.log('Nastavljam najnižjo kakovost zaradi počasne povezave'); + } else if (effectiveType === '3g' || downlink < 3) { hls.startLevel = Math.min(1, data.levels.length - 1); + console.log('Nastavljam nizko kakovost zaradi 3G povezave'); } } }); - // Quality level monitoring + // Quality level monitoring with detailed stats hls.on(Hls.Events.LEVEL_SWITCHED, (event, data) => { const level = hls.levels[data.level]; - console.log(`Kakovost preklopljena na: ${level.height}p @ ${Math.round(level.bitrate/1000)}kbps`); + console.log(`PREKLOPIL KAKOVOST: ${level.height}p @ ${Math.round(level.bitrate/1000)}kbps`); + console.log('Razlog preklopa: adaptivni algoritem na podlagi omrežne hitrosti'); + }); + + // Fragment loading stats + hls.on(Hls.Events.FRAG_LOADED, (event, data) => { + const stats = data.stats; + const loadTime = stats.loading.end - stats.loading.start; + const speed = (stats.total * 8) / loadTime; // bits per ms = kbps + console.log(`Fragment naložen v ${loadTime}ms, hitrost: ${Math.round(speed)} kbps`); }); // Buffer monitoring for dynamic adjustment