mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add ability to set playback speed on motion playback (#10628)
* Allow control of playback rate on motion page * Apply playback rate
This commit is contained in:
parent
76a114a3cd
commit
63bf986e08
@ -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}
|
||||
</div>
|
||||
|
@ -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<SVGElement>) => {
|
||||
e.stopPropagation();
|
||||
@ -177,7 +176,7 @@ export default function VideoControls({
|
||||
{features.seek && (
|
||||
<MdForward10 className="size-5 cursor-pointer" onClick={onSkip} />
|
||||
)}
|
||||
{video && features.playbackRate && (
|
||||
{features.playbackRate && (
|
||||
<DropdownMenu
|
||||
open={controlsOpen == true}
|
||||
onOpenChange={(open) => {
|
||||
@ -186,10 +185,10 @@ export default function VideoControls({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DropdownMenuTrigger>{`${video.playbackRate}x`}</DropdownMenuTrigger>
|
||||
<DropdownMenuTrigger>{`${playbackRate}x`}</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuRadioGroup
|
||||
onValueChange={(rate) => (video.playbackRate = parseFloat(rate))}
|
||||
onValueChange={(rate) => onSetPlaybackRate(parseFloat(rate))}
|
||||
>
|
||||
{playbackRates.map((rate) => (
|
||||
<DropdownMenuRadioItem key={rate} value={rate.toString()}>
|
||||
|
@ -716,11 +716,15 @@ function MotionReview({
|
||||
|
||||
// playback
|
||||
|
||||
const [playbackRate, setPlaybackRate] = useState(8);
|
||||
const [controlsOpen, setControlsOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!playing) {
|
||||
return;
|
||||
}
|
||||
|
||||
const interval = 500 / playbackRate;
|
||||
const startTime = currentTime;
|
||||
let counter = 0;
|
||||
const intervalId = setInterval(() => {
|
||||
@ -732,14 +736,14 @@ function MotionReview({
|
||||
}
|
||||
|
||||
setCurrentTime(startTime + counter);
|
||||
}, 60);
|
||||
}, interval);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
// do not render when current time changes
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [playing]);
|
||||
}, [playing, playbackRate]);
|
||||
|
||||
if (!relevantPreviews) {
|
||||
return <ActivityIndicator />;
|
||||
@ -815,9 +819,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 +840,7 @@ function MotionReview({
|
||||
setTimeout(() => setPlaying(true), 100);
|
||||
}
|
||||
}}
|
||||
onSetPlaybackRate={setPlaybackRate}
|
||||
show={currentTime < timeRange.before - 4}
|
||||
/>
|
||||
</>
|
||||
|
Loading…
Reference in New Issue
Block a user