[dyad] Add video trimming controls - wrote 1 file(s)

This commit is contained in:
[dyad]
2026-01-30 08:12:40 +01:00
parent ffd4b89308
commit 74ac37aa92

View File

@@ -1,15 +1,18 @@
"use client"; "use client";
import { useState, useRef, ChangeEvent } from "react"; import { useState, useRef, ChangeEvent, SyntheticEvent } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; 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 { UploadCloud, Scissors, Download } from "lucide-react"; import { UploadCloud, Scissors, Download } from "lucide-react";
export function VideoEditor() { export function VideoEditor() {
const [videoSrc, setVideoSrc] = useState<string | null>(null); const [videoSrc, setVideoSrc] = useState<string | null>(null);
const [videoFile, setVideoFile] = useState<File | null>(null); const [videoFile, setVideoFile] = useState<File | null>(null);
const [duration, setDuration] = useState(0);
const [trimValues, setTrimValues] = useState([0, 0]);
const videoRef = useRef<HTMLVideoElement>(null); const videoRef = useRef<HTMLVideoElement>(null);
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => { const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
@@ -21,6 +24,24 @@ export function VideoEditor() {
} }
}; };
const handleLoadedMetadata = (e: SyntheticEvent<HTMLVideoElement>) => {
const video = e.currentTarget;
setDuration(video.duration);
setTrimValues([0, video.duration]);
};
const formatTime = (timeInSeconds: number) => {
if (isNaN(timeInSeconds) || timeInSeconds < 0) {
return "00:00.000";
}
const minutes = Math.floor(timeInSeconds / 60);
const seconds = Math.floor(timeInSeconds % 60);
const milliseconds = Math.floor((timeInSeconds % 1) * 1000);
return `${String(minutes).padStart(2, "0")}:${String(
seconds
).padStart(2, "0")}.${String(milliseconds).padStart(3, "0")}`;
};
return ( return (
<Card className="w-full shadow-lg rounded-2xl border-0"> <Card className="w-full shadow-lg rounded-2xl border-0">
<CardHeader className="text-center"> <CardHeader className="text-center">
@@ -40,13 +61,24 @@ export function VideoEditor() {
src={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}
/> />
</div> </div>
<div> <div>
<h3 className="text-lg font-semibold mb-2">Trim Video</h3> <h3 className="text-lg font-semibold mb-4">Trim Video</h3>
<p className="text-sm text-muted-foreground"> <div className="space-y-4">
Trimming controls will be added here in the next step. <Slider
</p> value={trimValues}
onValueChange={setTrimValues}
max={duration}
step={0.1}
aria-label="Video trimmer"
/>
<div className="flex justify-between text-sm font-mono text-muted-foreground">
<span>Start: {formatTime(trimValues[0])}</span>
<span>End: {formatTime(trimValues[1])}</span>
</div>
</div>
</div> </div>
</div> </div>
) : ( ) : (