[dyad] Keep full video timeline after trimming - wrote 1 file(s)
This commit is contained in:
@@ -7,7 +7,7 @@ import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Slider } from "@/components/ui/slider";
|
||||
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 { fetchFile } from "@ffmpeg/util";
|
||||
|
||||
@@ -26,6 +26,26 @@ export function VideoEditor() {
|
||||
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 file = event.target.files?.[0];
|
||||
if (file) {
|
||||
@@ -43,6 +63,17 @@ export function VideoEditor() {
|
||||
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) => {
|
||||
if (isNaN(timeInSeconds) || timeInSeconds < 0) {
|
||||
return "00:00.000";
|
||||
@@ -101,12 +132,6 @@ export function VideoEditor() {
|
||||
setIsTrimming(false);
|
||||
};
|
||||
|
||||
const handleUntrim = () => {
|
||||
setTrimmedVideoUrl(null);
|
||||
setTrimValues([0, duration]);
|
||||
setProgress(0);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="w-full shadow-lg rounded-2xl border">
|
||||
<CardHeader className="text-center">
|
||||
@@ -123,11 +148,10 @@ export function VideoEditor() {
|
||||
<div className="aspect-video w-full overflow-hidden rounded-lg border">
|
||||
<video
|
||||
ref={videoRef}
|
||||
src={trimmedVideoUrl || videoSrc}
|
||||
src={videoSrc}
|
||||
controls
|
||||
className="w-full h-full object-contain bg-black"
|
||||
onLoadedMetadata={handleLoadedMetadata}
|
||||
key={trimmedVideoUrl} // Re-render video element when trimmed url changes
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -135,7 +159,7 @@ export function VideoEditor() {
|
||||
<div className="space-y-4">
|
||||
<Slider
|
||||
value={trimValues}
|
||||
onValueChange={setTrimValues}
|
||||
onValueChange={handleTrimValueChange}
|
||||
max={duration}
|
||||
step={0.1}
|
||||
aria-label="Video trimmer"
|
||||
@@ -181,12 +205,6 @@ export function VideoEditor() {
|
||||
</CardContent>
|
||||
{videoSrc && (
|
||||
<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}>
|
||||
{isTrimming ? (
|
||||
<Loader2 className="mr-2 h-5 w-5 animate-spin" />
|
||||
|
||||
Reference in New Issue
Block a user