This commit improves the snapping feature in the VideoEditor class by adding the ability to snap new tracking points to the closest point on the line segment between consecutive tracking points, in addition to existing point snapping. The distance calculation logic has been refined, and the specification has been updated to reflect the new snapping behavior, which now operates within a 10px radius for both point and line snapping, enhancing the precision of motion tracking.
7.4 KiB
Croppa - Feature Specification
Overview
Croppa is a lightweight video and image editor that provides real-time editing capabilities with persistent state management.
Notes:
Note the distinction between lowercase and uppercase keys Uppercase keys imply shift+key
Note that every transformation (cropping, motion track points) are almost always applied to an already transformed frame Be that by rotation, cropping, zooming or motion tracking itself Which means that the user input must be "de-transformed" before being applied to the frame In other words if we zoom into an area and right click to add a tracking point it must be added to that exact pixel ON THE ORIGINAL FRAME And NOT the zoomed in / processed frame Likwise with rotations All coordinates (crop region, zoom center, motion tracking point) are to be in reference to the original raw unprocessed frame To then display these points they must be transformed to the processed - display - frame Likewise when accepting user input from the processed display frame the coordinates must be transformed back to the original raw unprocessed frame A simple example if we are rotated by 90 degrees and click on the top left corner of the display frame That coordinate is to be mapped to the bottom left corner of the original raw unprocessed frame
The input to the editor is either a list of video files Or a directory In the case a directory is provided the editor is to open "all" editable files in the given directory In the case multiple files are open we are able to navigate between them using n and N keys for next and previous file Be careful to save and load settings when navigating this way
Core Features
Video Playback
- Space: Play/pause video
- a/d: Seek backward/forward 1 frame
- A/D: Seek backward/forward 10 frames
- Ctrl+a/d: Seek backward/forward 60 frames
- Mouse Wheel: Seek backward/forward 1 frame (ignores seek multiplier)
- W/S: Increase/decrease playback speed (0.1x to 10.0x, increments of 0.2)
- Q/Y: Increase/decrease seek multiplier (multiplies the frame count for a/d/A/D/Ctrl+a/d keys by 1.0x to 100.0x, increments of 2.0)
- q: Quit the program
- Timeline: Click anywhere to jump to that position
- Auto-repeat: Hold seek keys for continuous seeking at 1 FPS rate
Visual Transformations
- -: Rotate 90 degrees clockwise
- e/E: Increase/decrease brightness (-100 to +100, increments of 5)
- r/R: Increase/decrease contrast (0.1 to 3.0, increments of 0.1)
- Ctrl+Scroll: Zoom in/out (0.1x to 10.0x, increments of 0.1)
- Ctrl+Click: Set zoom center point
Cropping
- Shift+Click+Drag: Select crop area with green rectangle preview
- h/j/k/l: Expand crop from right/down/up/left edges (15 pixels per keypress)
- H/J/K/L: Contract crop to left/down/up/right edges (15 pixels per keypress)
- u: Undo last crop
- c: Clear all cropping
- C: Complete reset (crop, zoom, rotation, brightness, contrast, tracking points, cut markers)
Motion Tracking
- Right-click: Add tracking point (green circle with white border)
- Right-click existing point: Remove tracking point (within 10px)
- Right-click near existing point: Snap to existing point from any frame (within 10px radius)
- Right-click near motion path: Snap to closest point on yellow arrow line between tracking points (within 10px radius)
- v: Toggle motion tracking on/off
- V: Clear all tracking points
- Blue cross: Shows computed tracking position
- Automatic interpolation: Tracks between keyframes
- Crop follows: Crop area centers on tracked object
- Display Points are rendered as blue dots per frame, in addition the previous tracking point (red) and next tracking point (magenta) are shown with yellow arrows indicating motion direction
Motion Tracking Navigation
- ,: Jump to previous tracking marker (previous frame that has one or more tracking points). Wrap-around supported.
- .: Jump to next tracking marker (next frame that has one or more tracking points). Wrap-around supported.
Markers and Looping
- 1: Set cut start marker at current frame
- 2: Set cut end marker at current frame
- t: Toggle loop playback between markers
- Red lines: Markers shown on timeline with numbers
- Continuous loop: Playback loops between markers when enabled
File Management
- Enter: Render video (overwrites if filename contains "edited")
- b: Render video with new "_edited_001" filename (does NOT overwrite!)
- s: Save screenshot with auto-incrementing filename (video_frame_00001.jpg, video_frame_00002.jpg, etc. - NEVER overwrite existing screenshots)
- N/n: Next/previous video in directory
- p: Toggle project view (directory browser)
Project View
- wasd: Navigate through video thumbnails
- e: Open selected video
- Q/Y: Change thumbnail size (fewer/more per row, size automatically computed to fit row)
- q: Quit
- Progress bars: Show editing progress for each video (blue bar showing current_frame/total_frames)
- ESC: Return to editor
Display and Interface
- f: Toggle fullscreen
- Status overlay: Shows "Frame: 1500/3000 | Speed: 1.5x | Zoom: 2.0x | Seek: 5.0x | Rotation: 90° | Brightness: 10 | Contrast: 1.2 | Motion: ON (3 pts) | Playing/Paused"
- Timeline: Visual progress bar with current position handle
- Feedback messages: Temporary on-screen notifications (e.g. "Screenshot saved: video_frame_00001.jpg")
- Progress bar: Shows rendering progress with FPS counter (e.g. "Processing 1500/3000 frames | 25.3 FPS")
State Management
- Auto-save: Settings saved automatically on changes and on quit
- Per-video state: Each video remembers its own settings
- Cross-session: Settings persist between application restarts
- JSON files: State stored as .json files next to videos with the same name as the video
Rendering
- Background rendering: Continue editing while rendering (rendering happens in separate thread, you can still seek/play/edit)
- x: Cancel active render
- FFmpeg output: Invoke FFmpeg process, pipe raw video frames via stdin, output MP4 with H.264 encoding (CRF 18, preset fast)
- Progress tracking: Real-time progress with FPS display
- Overwrite protection: Only overwrites files with "edited" in name
Image Mode
- Same controls: All editing features work on static images
- No playback: Space key disabled, no timeline
- Screenshot mode: Treats single images like video frames
Error Handling
- Format support: MP4, AVI, MOV, MKV, WMV, FLV, WebM, M4V, JPG, PNG, BMP, TIFF, WebP
- Backend fallback: Tries multiple video backends automatically
- Error messages: Clear feedback for common issues
- Graceful degradation: Continues working when possible
Performance Features
- Frame caching: Smooth seeking with cached frames (cache the decoded frames, LRU eviction, max 3000 frames)
- Transformation caching: Fast repeated operations (cache transformed frames during auto-repeat seeking)
- Memory management: Automatic cache cleanup
Window Management
- Resizable: Window can be resized dynamically
- Multi-window: Project view opens in separate window
- Focus handling: Keys only affect active window
- Context menu: Right-click integration on Windows
This specification describes what Croppa does from the user's perspective - the features, controls, and behaviors that make up the application.