diff options
| author | iza <59828082+izadoesdev@users.noreply.github.com> | 2025-06-23 17:53:13 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-23 17:53:13 +0300 |
| commit | 13817a5ff847762a3ac4eb7cb09d17012b59e520 (patch) | |
| tree | 7c9b5fc69bbe86dfa66746c6a61da57a951bd1e9 /apps/web/src/components/ui | |
| parent | c8f92a76e30fba860b30a9b528e5b42291d2d54a (diff) | |
| parent | 9c61b72bd401d2a50b876bb2afbd571f7403a8e4 (diff) | |
| download | opencut-13817a5ff847762a3ac4eb7cb09d17012b59e520.tar.gz | |
Merge pull request #15 from StarKnightt/feature/speed-control
Add video speed control and improve playback smoothness
Diffstat (limited to 'apps/web/src/components/ui')
| -rw-r--r-- | apps/web/src/components/ui/command.tsx | 2 | ||||
| -rw-r--r-- | apps/web/src/components/ui/video-player.tsx | 23 |
2 files changed, 20 insertions, 5 deletions
diff --git a/apps/web/src/components/ui/command.tsx b/apps/web/src/components/ui/command.tsx index 29f29cf2..11b27041 100644 --- a/apps/web/src/components/ui/command.tsx +++ b/apps/web/src/components/ui/command.tsx @@ -1,7 +1,7 @@ "use client"; import * as React from "react"; -import { type DialogProps } from "radix-ui"; +import { DialogProps } from "@radix-ui/react-dialog"; import { Command as CommandPrimitive } from "cmdk"; import { Search } from "lucide-react"; diff --git a/apps/web/src/components/ui/video-player.tsx b/apps/web/src/components/ui/video-player.tsx index 0c4f8498..8731e1a8 100644 --- a/apps/web/src/components/ui/video-player.tsx +++ b/apps/web/src/components/ui/video-player.tsx @@ -25,7 +25,7 @@ export function VideoPlayer({ clipDuration }: VideoPlayerProps) { const videoRef = useRef<HTMLVideoElement>(null); - const { isPlaying, currentTime, volume, play, pause, setVolume } = usePlaybackStore(); + const { isPlaying, currentTime, volume, speed, play, pause, setVolume } = usePlaybackStore(); // Calculate if we're within this clip's timeline range const clipEndTime = clipStartTime + (clipDuration - trimStart - trimEnd); @@ -59,18 +59,26 @@ export function VideoPlayer({ timelineTime - clipStartTime + trimStart )); - // Only sync if there's a significant difference - if (Math.abs(video.currentTime - targetVideoTime) > 0.2) { + // Only sync if there's a significant difference to avoid micro-adjustments + if (Math.abs(video.currentTime - targetVideoTime) > 0.5) { video.currentTime = targetVideoTime; } }; + const handleSpeedEvent = (e: CustomEvent) => { + if (!isInClipRange) return; + // Set playbackRate directly without any additional checks + video.playbackRate = e.detail.speed; + }; + window.addEventListener("playback-seek", handleSeekEvent as EventListener); window.addEventListener("playback-update", handleUpdateEvent as EventListener); + window.addEventListener("playback-speed", handleSpeedEvent as EventListener); return () => { window.removeEventListener("playback-seek", handleSeekEvent as EventListener); window.removeEventListener("playback-update", handleUpdateEvent as EventListener); + window.removeEventListener("playback-speed", handleSpeedEvent as EventListener); }; }, [clipStartTime, trimStart, trimEnd, clipDuration, isInClipRange]); @@ -93,6 +101,13 @@ export function VideoPlayer({ video.volume = volume; }, [volume]); + // Sync speed immediately when it changes + useEffect(() => { + const video = videoRef.current; + if (!video) return; + video.playbackRate = speed; + }, [speed]); + return ( <div className={`relative group ${className}`}> <video @@ -101,7 +116,7 @@ export function VideoPlayer({ poster={poster} className="w-full h-full object-cover" playsInline - preload="metadata" + preload="auto" /> <div className="absolute inset-0 bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" /> |
