Allow control of playback rate on motion page

This commit is contained in:
Nicolas Mowen 2024-03-23 09:45:04 -06:00
parent 4159334520
commit fbfc53937a
3 changed files with 23 additions and 12 deletions

View File

@ -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>

View File

@ -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()}>

View File

@ -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}
/>
</>