diff --git a/web/src/components/player/HlsVideoPlayer.tsx b/web/src/components/player/HlsVideoPlayer.tsx index 088db8263..c12cffde3 100644 --- a/web/src/components/player/HlsVideoPlayer.tsx +++ b/web/src/components/player/HlsVideoPlayer.tsx @@ -75,6 +75,8 @@ export default function HlsVideoPlayer({ // controls const [isPlaying, setIsPlaying] = useState(true); + const [muted, setMuted] = useState(true); + const [volume, setVolume] = useState(1.0); const [mobileCtrlTimeout, setMobileCtrlTimeout] = useState(); const [controls, setControls] = useState(isMobile); const [controlsOpen, setControlsOpen] = useState(false); @@ -85,9 +87,12 @@ export default function HlsVideoPlayer({ className="absolute bottom-5 left-1/2 -translate-x-1/2 z-50" video={videoRef.current} isPlaying={isPlaying} - show={controls} + show={visible && controls} + muted={muted} + volume={volume} controlsOpen={controlsOpen} setControlsOpen={setControlsOpen} + setMuted={setMuted} playbackRate={videoRef.current?.playbackRate ?? 1} hotKeys={hotKeys} onPlayPause={(play) => { @@ -155,7 +160,8 @@ export default function HlsVideoPlayer({ autoPlay controls={false} playsInline - muted + muted={muted} + onVolumeChange={() => setVolume(videoRef.current?.volume ?? 1.0)} onPlay={() => { setIsPlaying(true); diff --git a/web/src/components/player/VideoControls.tsx b/web/src/components/player/VideoControls.tsx index 4ee9374fa..4dc7962ee 100644 --- a/web/src/components/player/VideoControls.tsx +++ b/web/src/components/player/VideoControls.tsx @@ -38,11 +38,14 @@ type VideoControlsProps = { features?: VideoControls; isPlaying: boolean; show: boolean; + muted: boolean; + volume: number; controlsOpen?: boolean; playbackRates?: number[]; playbackRate: number; hotKeys?: boolean; setControlsOpen?: (open: boolean) => void; + setMuted: (muted: boolean) => void; onPlayPause: (play: boolean) => void; onSeek: (diff: number) => void; onSetPlaybackRate: (rate: number) => void; @@ -53,11 +56,14 @@ export default function VideoControls({ features = CONTROLS_DEFAULT, isPlaying, show, + muted, + volume, controlsOpen, playbackRates = PLAYBACK_RATE_DEFAULT, playbackRate, hotKeys = true, setControlsOpen, + setMuted, onPlayPause, onSeek, onSetPlaybackRate, @@ -89,18 +95,18 @@ export default function VideoControls({ // volume control const VolumeIcon = useMemo(() => { - if (!video || video?.muted) { + if (volume == 0.0 || muted) { return MdVolumeOff; - } else if (video.volume <= 0.33) { + } else if (volume <= 0.33) { return MdVolumeMute; - } else if (video.volume <= 0.67) { + } else if (volume <= 0.67) { return MdVolumeDown; } else { return MdVolumeUp; } // only update when specific fields change // eslint-disable-next-line react-hooks/exhaustive-deps - }, [video?.volume, video?.muted]); + }, [volume, muted]); const onKeyboardShortcut = useCallback( (key: string, down: boolean, repeat: boolean) => { @@ -117,7 +123,7 @@ export default function VideoControls({ break; case "m": if (down && !repeat && video) { - video.muted = !video.muted; + setMuted(!muted); } break; case " ": @@ -150,13 +156,13 @@ export default function VideoControls({ className="size-5" onClick={(e: React.MouseEvent) => { e.stopPropagation(); - video.muted = !video.muted; + setMuted(!muted); }} /> - {video.muted == false && ( + {muted == false && ( onSetPlaybackRate(parseFloat(rate))} > {playbackRates.map((rate) => ( - + {rate}x ))}