diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 28965ea..c5ecf2c 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -262,8 +262,22 @@ function MediaTrack({ track, muted = false, className = '' }) { function RemoteAudioTrack({ track, volume }) { + const audioRef = useRef(null); const gainRef = useRef(null); + useEffect(() => { + if (!track || !audioRef.current) return undefined; + track.attach(audioRef.current); + return () => { + track.detach(audioRef.current); + }; + }, [track]); + + useEffect(() => { + if (!audioRef.current) return; + audioRef.current.volume = Math.min(1, Math.max(0, volume)); + }, [volume]); + useEffect(() => { if (!track?.mediaStreamTrack) return undefined; const AudioContextClass = window.AudioContext || window.webkitAudioContext; @@ -272,10 +286,10 @@ function RemoteAudioTrack({ track, volume }) { const stream = new MediaStream([track.mediaStreamTrack]); const source = context.createMediaStreamSource(stream); const gain = context.createGain(); - gain.gain.value = volume; + gain.gain.value = Math.max(0, volume - 1); source.connect(gain); gain.connect(context.destination); - gainRef.current = gain; + gainRef.current = { context, gain }; context.resume().catch(() => {}); return () => { @@ -287,14 +301,14 @@ function RemoteAudioTrack({ track, volume }) { }, [track]); useEffect(() => { - if (gainRef.current) gainRef.current.gain.value = volume; + if (gainRef.current) gainRef.current.gain.gain.value = Math.max(0, volume - 1); }, [volume]); - return null; + return ; } -function VideoTile({ item, active, volume, onVolumeChange }) { +function VideoTile({ item, active, volume, volumeMenuOpen, onScreenFullscreen, onToggleVolumeMenu, onVolumeChange }) { const camera = item.tracks.find((entry) => entry.kind === 'video' && entry.source !== Track.Source.ScreenShare); const screen = item.tracks.find((entry) => entry.kind === 'video' && entry.source === Track.Source.ScreenShare); const audio = item.tracks.filter((entry) => entry.kind === 'audio'); @@ -302,24 +316,45 @@ function VideoTile({ item, active, volume, onVolumeChange }) { const volumePercent = Math.round(volume * 100); return ( -
В комнате: {participants.length}
-