[dyad] Keep full video timeline after trimming - wrote 1 file(s)

This commit is contained in:
[dyad]
2026-01-30 08:24:02 +01:00
parent 52edd3e450
commit ec60edcc4b

View File

@@ -7,7 +7,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Slider } from "@/components/ui/slider"; import { Slider } from "@/components/ui/slider";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import { UploadCloud, Scissors, Download, Loader2, RotateCcw } from "lucide-react"; import { UploadCloud, Scissors, Download, Loader2 } from "lucide-react";
import { getFFmpeg } from "@/lib/ffmpeg"; import { getFFmpeg } from "@/lib/ffmpeg";
import { fetchFile } from "@ffmpeg/util"; import { fetchFile } from "@ffmpeg/util";
@@ -26,6 +26,26 @@ export function VideoEditor() {
getFFmpeg(); getFFmpeg();
}, []); }, []);
useEffect(() => {
const video = videoRef.current;
if (!video) return;
const handleTimeUpdate = () => {
if (video.currentTime > trimValues[1]) {
video.pause();
video.currentTime = trimValues[0];
}
};
video.addEventListener('timeupdate', handleTimeUpdate);
return () => {
if (video) {
video.removeEventListener('timeupdate', handleTimeUpdate);
}
};
}, [trimValues]);
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => { const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0]; const file = event.target.files?.[0];
if (file) { if (file) {
@@ -43,6 +63,17 @@ export function VideoEditor() {
setTrimValues([0, video.duration]); setTrimValues([0, video.duration]);
}; };
const handleTrimValueChange = (newValues: number[]) => {
if (videoRef.current) {
if (newValues[0] !== trimValues[0]) {
videoRef.current.currentTime = newValues[0];
} else if (newValues[1] !== trimValues[1]) {
videoRef.current.currentTime = newValues[1];
}
}
setTrimValues(newValues);
};
const formatTime = (timeInSeconds: number) => { const formatTime = (timeInSeconds: number) => {
if (isNaN(timeInSeconds) || timeInSeconds < 0) { if (isNaN(timeInSeconds) || timeInSeconds < 0) {
return "00:00.000"; return "00:00.000";
@@ -101,12 +132,6 @@ export function VideoEditor() {
setIsTrimming(false); setIsTrimming(false);
}; };
const handleUntrim = () => {
setTrimmedVideoUrl(null);
setTrimValues([0, duration]);
setProgress(0);
};
return ( return (
<Card className="w-full shadow-lg rounded-2xl border"> <Card className="w-full shadow-lg rounded-2xl border">
<CardHeader className="text-center"> <CardHeader className="text-center">
@@ -123,11 +148,10 @@ export function VideoEditor() {
<div className="aspect-video w-full overflow-hidden rounded-lg border"> <div className="aspect-video w-full overflow-hidden rounded-lg border">
<video <video
ref={videoRef} ref={videoRef}
src={trimmedVideoUrl || videoSrc} src={videoSrc}
controls controls
className="w-full h-full object-contain bg-black" className="w-full h-full object-contain bg-black"
onLoadedMetadata={handleLoadedMetadata} onLoadedMetadata={handleLoadedMetadata}
key={trimmedVideoUrl} // Re-render video element when trimmed url changes
/> />
</div> </div>
<div> <div>
@@ -135,7 +159,7 @@ export function VideoEditor() {
<div className="space-y-4"> <div className="space-y-4">
<Slider <Slider
value={trimValues} value={trimValues}
onValueChange={setTrimValues} onValueChange={handleTrimValueChange}
max={duration} max={duration}
step={0.1} step={0.1}
aria-label="Video trimmer" aria-label="Video trimmer"
@@ -181,12 +205,6 @@ export function VideoEditor() {
</CardContent> </CardContent>
{videoSrc && ( {videoSrc && (
<CardFooter className="flex justify-end space-x-4 p-6"> <CardFooter className="flex justify-end space-x-4 p-6">
{trimmedVideoUrl && (
<Button variant="ghost" size="lg" onClick={handleUntrim} disabled={isTrimming}>
<RotateCcw className="mr-2 h-5 w-5" />
Reset
</Button>
)}
<Button variant="outline" size="lg" onClick={handleCutVideo} disabled={isTrimming}> <Button variant="outline" size="lg" onClick={handleCutVideo} disabled={isTrimming}>
{isTrimming ? ( {isTrimming ? (
<Loader2 className="mr-2 h-5 w-5 animate-spin" /> <Loader2 className="mr-2 h-5 w-5 animate-spin" />