From fbfc53937a243416b8e8729df554f42fb49cadff Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sat, 23 Mar 2024 09:45:04 -0600 Subject: [PATCH] Allow control of playback rate on motion page --- web/src/components/player/HlsVideoPlayer.tsx | 4 ++++ web/src/components/player/VideoControls.tsx | 21 ++++++++++---------- web/src/views/events/EventView.tsx | 10 +++++++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/web/src/components/player/HlsVideoPlayer.tsx b/web/src/components/player/HlsVideoPlayer.tsx index e40754339..9a7814798 100644 --- a/web/src/components/player/HlsVideoPlayer.tsx +++ b/web/src/components/player/HlsVideoPlayer.tsx @@ -160,6 +160,7 @@ export default function HlsVideoPlayer({ show={controls} controlsOpen={controlsOpen} setControlsOpen={setControlsOpen} + playbackRate={videoRef.current?.playbackRate ?? 1} onPlayPause={(play) => { if (!videoRef.current) { return; @@ -180,6 +181,9 @@ export default function HlsVideoPlayer({ videoRef.current.currentTime = Math.max(0, currentTime + diff); }} + onSetPlaybackRate={(rate) => + videoRef.current ? (videoRef.current.playbackRate = rate) : null + } /> {children} diff --git a/web/src/components/player/VideoControls.tsx b/web/src/components/player/VideoControls.tsx index b8044c687..f6fa19d12 100644 --- a/web/src/components/player/VideoControls.tsx +++ b/web/src/components/player/VideoControls.tsx @@ -30,6 +30,7 @@ const CONTROLS_DEFAULT: VideoControls = { seek: true, playbackRate: true, }; +const PLAYBACK_RATE_DEFAULT = isSafari ? [0.5, 1, 2] : [0.5, 1, 2, 4, 8, 16]; type VideoControlsProps = { className?: string; @@ -38,9 +39,12 @@ type VideoControlsProps = { isPlaying: boolean; show: boolean; controlsOpen?: boolean; + playbackRates?: number[]; + playbackRate: number; setControlsOpen?: (open: boolean) => void; onPlayPause: (play: boolean) => void; onSeek: (diff: number) => void; + onSetPlaybackRate: (rate: number) => void; }; export default function VideoControls({ className, @@ -49,18 +53,13 @@ export default function VideoControls({ isPlaying, show, controlsOpen, + playbackRates = PLAYBACK_RATE_DEFAULT, + playbackRate, setControlsOpen, onPlayPause, onSeek, + onSetPlaybackRate, }: VideoControlsProps) { - const playbackRates = useMemo(() => { - if (isSafari) { - return [0.5, 1, 2]; - } else { - return [0.5, 1, 2, 4, 8, 16]; - } - }, []); - const onReplay = useCallback( (e: React.MouseEvent) => { e.stopPropagation(); @@ -177,7 +176,7 @@ export default function VideoControls({ {features.seek && ( )} - {video && features.playbackRate && ( + {features.playbackRate && ( { @@ -186,10 +185,10 @@ export default function VideoControls({ } }} > - {`${video.playbackRate}x`} + {`${playbackRate}x`} (video.playbackRate = parseFloat(rate))} + onValueChange={(rate) => onSetPlaybackRate(parseFloat(rate))} > {playbackRates.map((rate) => ( diff --git a/web/src/views/events/EventView.tsx b/web/src/views/events/EventView.tsx index 156d16b2d..094c7f539 100644 --- a/web/src/views/events/EventView.tsx +++ b/web/src/views/events/EventView.tsx @@ -716,6 +716,9 @@ function MotionReview({ // playback + const [playbackRate, setPlaybackRate] = useState(8); + const [controlsOpen, setControlsOpen] = useState(false); + useEffect(() => { if (!playing) { return; @@ -815,9 +818,13 @@ function MotionReview({ features={{ volume: false, seek: true, - playbackRate: false, + playbackRate: true, }} isPlaying={playing} + playbackRates={[4, 8, 12, 16]} + playbackRate={playbackRate} + controlsOpen={controlsOpen} + setControlsOpen={setControlsOpen} onPlayPause={setPlaying} onSeek={(diff) => { const wasPlaying = playing; @@ -832,6 +839,7 @@ function MotionReview({ setTimeout(() => setPlaying(true), 100); } }} + onSetPlaybackRate={setPlaybackRate} show={currentTime < timeRange.before - 4} />