REFACTOR sliders into different files

This commit is contained in:
2025-05-23 11:39:29 +02:00
parent 62af69e45b
commit a25564dd31
5 changed files with 125 additions and 66 deletions

View File

@@ -0,0 +1,40 @@
import {VideoMetadata} from "Frontend/components/Playbar";
import RangeSlider from 'react-range-slider-input';
import 'react-range-slider-input/dist/style.css';
import {useRef} from "react";
import clsx from 'clsx';
type Props = {
videoRef: HTMLVideoElement | null;
videoMetadata: VideoMetadata;
setSliderValue: Function;
className?: string;
};
export default function ClipRangeSlider({videoRef, videoMetadata, setSliderValue, className}: Props) {
const previousRangeSliderInput = useRef<[number, number]>([0, 0]);
const handleRangeSliderInput = (val: [number, number]) => {
if (!videoRef) return;
if (previousRangeSliderInput.current[0] != val[0]) {
videoRef.currentTime = val[0];
setSliderValue(val[0]);
} else if (previousRangeSliderInput.current[1] != val[1]) {
videoRef.currentTime = val[1];
setSliderValue(val[1]);
}
previousRangeSliderInput.current = val;
};
return (
<RangeSlider
min={0}
max={videoMetadata.endPoint}
step={0.1}
onInput={handleRangeSliderInput}
className={clsx(className)}
/>
)
}

View File

@@ -0,0 +1,51 @@
import {VideoMetadata} from "Frontend/components/Playbar";
import {useEffect, useState} from "react";
import clsx from 'clsx';
type Props = {
videoRef: HTMLVideoElement | null;
videoMetadata: VideoMetadata;
sliderValue: number;
setSliderValue: Function;
className?: string;
};
export default function PlaybackSlider({videoRef,
videoMetadata,
sliderValue,
setSliderValue,
className}: Props) {
const updateVideo = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!videoRef) return;
videoRef.currentTime = e.target.valueAsNumber;
setSliderValue(e.target.valueAsNumber);
}
// update slider
useEffect(() => {
if (!videoRef) return;
const updateSlider = () => {
setSliderValue(videoRef.currentTime);
};
videoRef.addEventListener("timeupdate", updateSlider);
return () => {
videoRef.removeEventListener("timeupdate", updateSlider);
};
}, [videoRef]);
return (
<input
type={"range"}
min={0}
max={videoMetadata.endPoint}
value={sliderValue}
onChange={updateVideo}
step={0.1}
className={clsx(className)}
/>
)
}

View File

@@ -1,42 +1,17 @@
import { useParams } from 'react-router-dom';
import { useEffect, useRef, useState } from "react";
import RangeSlider from 'react-range-slider-input';
import 'react-range-slider-input/dist/style.css';
import Playbar, {VideoMetadata } from "./../../components/Playbar"
import { VideoMetadata } from "Frontend/components/Playbar";
import Playbar from "./../../components/Playbar"
import PlaybackSlider from "./../../components/PlaybackSlider"
import ClipRangeSlider from "./../../components/ClipRangeSlider"
export default function VideoId() {
const { id } = useParams();
const videoRef = useRef<HTMLVideoElement | null>(null);
const videoUrl = "api/v1/download/input/" + id;
const videoUrl = `api/v1/download/input/${id}`
const [metadata, setMetadata] = useState<VideoMetadata | null>(null);
const [sliderValue, setSliderValue] = useState(0);
const previousRangeSliderInput = useRef<[number, number]>([0, 0]);
const handleRangeSliderInput = (val: [number, number]) => {
if (!videoRef.current) {
return;
}
if (previousRangeSliderInput.current[0] != val[0]) {
videoRef.current.currentTime = val[0];
setSliderValue(val[0]);
} else if (previousRangeSliderInput.current[1] != val[1]) {
videoRef.current.currentTime = val[1];
setSliderValue(val[1]);
}
previousRangeSliderInput.current = val;
};
const updateVideoTag = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!videoRef.current) {
return;
}
setSliderValue(parseFloat(e.target.value));
videoRef.current.currentTime = parseFloat(e.target.value);
};
useEffect(() => {
fetch(`api/v1/metadata/original/${id}`)
@@ -46,30 +21,13 @@ export default function VideoId() {
})
.then(setMetadata)
.catch((err) => console.log(err.message));
}, []);
// update slider
useEffect(() => {
const video = videoRef.current;
if (!video) return;
const updateSlider = () => {
setSliderValue(video.currentTime);
};
video.addEventListener("timeupdate", updateSlider);
return () => {
video.removeEventListener("timeupdate", updateSlider);
};
}, [videoRef]);
}, [id]);
return (
<div className={"flex flex-col gap-2 max-w-3xl m-auto align-middle "}>
<div className={"flex flex-col gap-2 max-w-3xl m-auto align-middle"}>
<video
ref={videoRef}
preload="metadata"
width="600"
width={"600"}
className={"w-full max-w-3xl rounded-lg shadow-lg border border-gray-300 bg-black m-auto"}>
<source src={videoUrl} type="video/mp4" />
<source src={videoUrl} type="video/webm" />
@@ -81,21 +39,20 @@ export default function VideoId() {
{metadata &&
<div>
<Playbar video={videoRef.current} videoMetadata={metadata}/>
<input
<PlaybackSlider
videoRef={videoRef.current}
videoMetadata={metadata}
sliderValue={sliderValue}
setSliderValue={setSliderValue}
className={"w-full"}
type="range"
min={0}
max={metadata.endPoint}
value={sliderValue}
onChange={updateVideoTag}
step={0.1}
/>
<RangeSlider
min={0}
max={metadata.endPoint}
step={0.1}
onInput={handleRangeSliderInput}/>
<ClipRangeSlider
videoRef={videoRef.current}
videoMetadata={metadata}
setSliderValue={setSliderValue}
className={"w-full"}
/>
</div>
}
</div>