Add video speed control and improve playback smoothness#15
Conversation
Added a speed control dropdown in the timeline toolbar that lets users change video playback speed between 0.5x to 2x. The dropdown shows the current speed and offers preset options. Made video playback smoother by: - Using better timing for speed changes - Improving video synchronization - Reducing playback stutters - Making speed changes more responsive The speed control is now easily accessible while editing and works smoothly with all video clips.
❌ Deploy Preview for appcut failed. Why did it fail? →
|
WalkthroughPlayback speed control was introduced and integrated across the editor. A new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant PropertiesPanel
participant SpeedControl
participant PlaybackStore
participant VideoPlayer
User->>PropertiesPanel: Selects a video clip
PropertiesPanel->>SpeedControl: Renders speed controls
User->>SpeedControl: Adjusts speed (button/slider)
SpeedControl->>PlaybackStore: setSpeed(newSpeed)
PlaybackStore-->>VideoPlayer: Dispatch playback-speed event
PlaybackStore-->>VideoPlayer: Update speed in store
VideoPlayer->>VideoPlayer: Update playbackRate to newSpeed
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/web/src/components/ui/video-player.tsx (1)
104-109: Consider potential redundancy in speed synchronizationThe component now has two mechanisms for syncing video speed:
- Event listener for
playback-speedevents (lines 68-72)useEffectthat syncs on speed changes (lines 104-109)While this ensures synchronization, it could cause redundant updates since both mechanisms respond to speed changes.
Consider whether both synchronization mechanisms are necessary, or if one could be sufficient for cleaner code and potentially better performance.
apps/web/src/components/editor/properties-panel.tsx (1)
29-39: Consider refactoring to reduce code duplication.The logic for finding the first video clip duplicates the pattern used for finding image clips. Consider extracting a reusable helper function to reduce duplication.
+ // Helper function to find first clip of a specific media type + const findFirstClipByType = (type: "video" | "image") => { + return tracks + .flatMap((track) => track.clips) + .find((clip) => { + const mediaItem = mediaItems.find((item) => item.id === clip.mediaId); + return mediaItem?.type === type; + }); + }; + // Get the first video clip for preview (simplified) - const firstVideoClip = tracks - .flatMap((track) => track.clips) - .find((clip) => { - const mediaItem = mediaItems.find((item) => item.id === clip.mediaId); - return mediaItem?.type === "video"; - }); + const firstVideoClip = findFirstClipByType("video");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/web/src/components/editor/properties-panel.tsx(1 hunks)apps/web/src/components/editor/speed-control.tsx(1 hunks)apps/web/src/components/editor/timeline.tsx(3 hunks)apps/web/src/components/ui/command.tsx(1 hunks)apps/web/src/components/ui/video-player.tsx(4 hunks)apps/web/src/stores/playback-store.ts(4 hunks)apps/web/src/types/playback.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/web/src/components/editor/speed-control.tsx (1)
apps/web/src/stores/playback-store.ts (1)
usePlaybackStore(45-93)
apps/web/src/components/ui/video-player.tsx (1)
apps/web/src/stores/playback-store.ts (1)
usePlaybackStore(45-93)
🔇 Additional comments (18)
apps/web/src/components/ui/command.tsx (1)
4-4: LGTM: Import specificity improvementGood change to import
DialogPropsdirectly from the specific Radix UI package rather than a generic import. This improves clarity and potentially enables better tree-shaking.apps/web/src/types/playback.ts (2)
6-6: LGTM: Appropriate type addition for speed stateThe
speedproperty addition toPlaybackStateproperly extends the interface to support playback speed functionality.
14-14: LGTM: Consistent method signature for speed controlThe
setSpeedmethod addition follows the same pattern as other control methods in the interface, maintaining consistency.apps/web/src/components/editor/timeline.tsx (3)
31-37: LGTM: Proper imports for Select componentsThe import of Select-related components is correctly added to support the new speed control dropdown in the timeline toolbar.
46-46: LGTM: Consistent playback store integrationProperly added
speedandsetSpeedto the playback store destructuring, maintaining consistency with existing playback controls.
342-363: LGTM: Well-integrated speed control in timeline toolbarThe speed control dropdown is excellently integrated:
- Properly positioned in the toolbar with appropriate visual separation
- Uses consistent speed format with
.toFixed(1)- Provides common speed presets (0.5x to 2.0x)
- Includes helpful tooltip for accessibility
- Maintains visual consistency with existing toolbar elements
The integration provides users with convenient access to speed control during timeline editing.
apps/web/src/components/editor/speed-control.tsx (2)
6-11: LGTM: Well-defined speed presetsThe
SPEED_PRESETSconstant provides sensible default speed options that match the timeline dropdown and align with common video editing workflows.
13-46: LGTM: Comprehensive speed control interfaceExcellent implementation providing both preset buttons and fine-grained slider control:
- Preset buttons use proper variant switching to indicate active state
- Slider range (0.1-2.0) with 0.1 step provides good granularity
- Speed display formatting is consistent throughout
- Component structure follows good React patterns
Verify that the slider's speed range (0.1-2.0) matches the clamping logic in the playback store to ensure consistency:
#!/bin/bash # Check playback store speed clamping range rg -A 5 -B 5 "setSpeed.*=>"apps/web/src/components/ui/video-player.tsx (5)
28-28: LGTM: Proper speed state integrationCorrectly added
speedto the playback store destructuring to support dynamic playback speed control.
63-63: Review the increased sync thresholdThe sync threshold was increased from 0.2 to 0.5 seconds. While this may reduce micro-adjustments and improve performance, it could affect playback precision for fine-grained synchronization needs.
Consider whether this threshold increase aligns with the desired playback smoothness and accuracy requirements for video editing workflows.
68-72: Verify clip range restriction for speed eventsThe speed event handler only updates playback rate when
isInClipRangeis true. This means speed changes won't affect videos outside their clip range, which may be inconsistent with user expectations.Consider whether speed changes should apply globally to all video elements or only to those currently in range. The current behavior might cause confusion if users expect speed changes to affect all videos immediately.
76-76: LGTM: Proper event listener managementEvent listener setup and cleanup for
playback-speedevents is correctly implemented with proper lifecycle management.Also applies to: 81-81
119-119: Review preload attribute changeChanged from
preload="metadata"topreload="auto". This may improve loading behavior for speed control responsiveness but will increase bandwidth usage as it loads entire videos upfront.Ensure this change aligns with performance requirements and acceptable bandwidth usage for the target use case.
apps/web/src/components/editor/properties-panel.tsx (1)
124-129: LGTM! Consistent conditional rendering pattern.The video controls conditional rendering follows the same pattern as image controls, maintaining consistency in the component structure.
apps/web/src/stores/playback-store.ts (4)
9-9: LGTM! Correct type change for requestAnimationFrame.The type change from
NodeJS.Timeout | nulltonumber | nullis correct for browserrequestAnimationFramehandles.
14-36: Verify timer logic handles edge cases correctly.The requestAnimationFrame approach with delta time calculation is a good improvement for smoother playback. However, there are a few potential concerns:
- The first frame might have an unexpectedly large delta if there's a delay between
lastUpdateinitialization and the firstupdateTimecall- The recursive
requestAnimationFramecall happens regardless of playing state, which could waste resourcesConsider adding safeguards for the first frame and optimizing the recursive calls:
const updateTime = () => { const state = store(); if (state.isPlaying && state.currentTime < state.duration) { const now = performance.now(); const delta = (now - lastUpdate) / 1000; // Convert to seconds + // Cap delta to prevent large jumps (e.g., after tab becomes active) + const cappedDelta = Math.min(delta, 0.1); // Max 100ms jump lastUpdate = now; - const newTime = state.currentTime + (delta * state.speed); + const newTime = state.currentTime + (cappedDelta * state.speed); if (newTime >= state.duration) { state.pause(); } else { state.setCurrentTime(newTime); // Notify video elements to sync window.dispatchEvent(new CustomEvent('playback-update', { detail: { time: newTime } })); } } - playbackTimer = requestAnimationFrame(updateTime); + // Only continue if still playing + if (state.isPlaying) { + playbackTimer = requestAnimationFrame(updateTime); + } };
50-50: LGTM! Appropriate default speed value.The default speed of 1.0 (normal speed) is appropriate and aligns with standard video player conventions.
83-89: LGTM! Proper speed clamping and event dispatch.The speed clamping between 0.1x and 2.0x is reasonable for most use cases, and the custom event dispatch pattern is consistent with other methods in the store.
Add video speed control and improve playback smoothness
Added a speed control dropdown in the timeline toolbar that lets users change video playback speed between 0.5x to 2x. The dropdown shows the current speed and offers preset options.
Made video playback smoother by:
The speed control is now easily accessible while editing and works smoothly with all video clips.
Description
This feature helps to make things faster or slower on the video as well as makes things better.
Fixes # (issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
completely working fine. awesome one
Test Configuration:
Screenshots (if applicable)
Here it is btw, simple and good, no extra things, simply makes your video faster or slower.
Checklist:
Additional context
Add any other context about the pull request here.
Summary by CodeRabbit
New Features
Improvements
Bug Fixes