Modules with handlers but missing dependencies now show orange
background with stripes instead of grey. This distinguishes them
from unimplemented modules (grey) and helps users identify what
needs to be installed.
Redesigned main menu for better space efficiency and visual organization:
- Changed from flexible GridWrap to fixed 3-column grid layout
- Organized modules into priority-based sections with category labels
- Category labels positioned above each section (Convert, Inspect, Disc, Playback)
- Reduced tile size from 150x65 to 135x58 for better spacing
- Removed excessive padding for more compact layout
- All 15 modules now visible in organized 3x5 grid
Layout organization:
- Row 1-2: Convert modules (Convert, Merge, Trim, Filters, Audio, Subtitles)
- Row 3: Inspect/Advanced (Compare, Inspect, Upscale)
- Row 4: Disc modules (Author, Rip, Blu-Ray)
- Row 5: Misc modules (Player, Thumb, Settings)
This addresses user feedback about wasted space and provides a more polished, professional appearance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
UI Scaling Improvements:
- Reduce module tiles from 160x80 to 150x65
- Reduce title from 20 to 18
- Reduce queue tile from 140x50 to 120x40
- Reduce category labels to 12px
- Reduce padding from 8 to 4px
- Remove scrolling, everything fits in 800x600
Preset UX Improvements:
- Move "Manual" to bottom of all preset dropdowns
- Default bitrate preset: "2.5 Mbps - Medium Quality"
- Default target size: "100MB"
- Manual input fields hidden by default
- Show manual fields only when "Manual" selected
Encoding Preset Order:
- Reverse order: veryslow first, ultrafast last
- Better quality options now appear first
- Applied to both simple and advanced mode
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
UI Scaling:
- Reduce module tiles from 220x110 to 160x80
- Reduce title size from 28 to 20
- Reduce queue tile from 160x60 to 140x50 with smaller text
- Reduce section padding from 14 to 8 pixels
- Remove extra padding wrapper around tiles
Header Layout Improvements:
- Use border layout with title on left, controls on right
- Compact button labels: "☰ History" → "☰", "Run Benchmark" → "Benchmark"
- Eliminates wasted space in header
Queue Behavior Fix:
- "Clear Completed" always returns to main menu (not last module)
- "Clear All" always returns to main menu
- Prevents unwanted navigation to convert module after clearing
All changes work together to fit app within 800x600 default window
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Wrap module sections in NewVScroll container
- Use border layout with fixed header and scrollable content
- Allows all modules to be accessible within 800x600 window
- Header and controls remain visible while content scrolls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace layout.NewHBoxLayout() with container.NewHBox() for header
- Replace layout.NewVBoxLayout() with container.NewVBox() for body
- Prevents unwanted stretching and improves alignment with rest of UI
- Elements now use natural sizing instead of filling available space
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
In Progress Tab Enhancements:
- Added animated striped progress bars to in-progress jobs
- Exported ModuleColor function for reuse across modules
- Shows real-time progress (0-100%) with module-specific colors
- Progress updates automatically as jobs run
- Maintains consistent visual style with queue view
Lossless Quality Preset Improvements:
- H.265 and AV1 now support all bitrate modes with lossless quality
- Lossless with Target Size mode now works for H.265/AV1
- H.264 and MPEG-2 no longer show "Lossless" option (codec limitation)
- Dynamic quality dropdown updates based on selected codec
- Automatic fallback to "Near-Lossless" when switching from lossless-capable
codec to non-lossless codec
Quality Options Logic:
- Base options: Draft, Standard, Balanced, High, Near-Lossless
- "Lossless" only appears for H.265 and AV1
- codecSupportsLossless() helper function checks compatibility
- updateQualityOptions() refreshes dropdown when codec changes
Lossless + Bitrate Mode Combinations:
- Lossless + CRF: Forces CRF 0 for perfect quality
- Lossless + CBR: Constant bitrate with lossless quality
- Lossless + VBR: Variable bitrate with lossless quality
- Lossless + Target Size: Calculates bitrate for exact file size with
best possible quality (now allowed for H.265/AV1)
Technical Implementation:
- Added Progress field to ui.HistoryEntry struct
- Exported StripedProgress widget and ModuleColor function
- updateQualityOptions() function dynamically filters quality presets
- updateEncodingControls() handles lossless modes per codec
- Descriptive hints explain each lossless+bitrate combination
This allows professional workflows where lossless quality is desired
but file size constraints still need to be met using Target Size mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- New "In Progress" tab shows running/pending jobs
- Displays active jobs without opening full queue
- Tab positioned first for quick visibility
- Shows "Running..." or "Pending" status
- No delete button on active jobs (only completed/failed)
Implementation:
- Updated BuildHistorySidebar to accept activeJobs parameter
- Converts queue.Job to ui.HistoryEntry for display
- Filters running/pending jobs from queue
- Conditional delete button (nil check)
- Dynamic status text based on job state
UX Improvements:
- Quick glance at current activity without queue view
- Three-tab layout: In Progress → Completed → Failed
- Consistent styling with existing history entries
- Tappable entries to view full job details
This allows users to monitor active conversions directly
from the history sidebar, reducing the need to constantly
check the full job queue view.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- Add "×" delete button to each history entry in sidebar
- Click to remove individual entries from history
- Automatically saves and refreshes sidebar after deletion
Bug Fixes:
- Fix nil pointer crash when opening Convert module
- Fixed widget initialization order: bitrateContainer now created
AFTER bitratePresetSelect is initialized
- Prevented "invalid memory address" panic in tabs layout
Technical Details:
- Added deleteHistoryEntry() method to remove entries by ID
- Updated BuildHistorySidebar signature to accept onEntryDelete callback
- Moved bitrateContainer creation from line 5742 to 5794
- All Select widgets now properly initialized before container creation
The crash was caused by bitrateContainer containing a nil
bitratePresetSelect widget, which crashed when Fyne's layout system
called .Visible() during tab initialization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Integrated history sidebar into main menu with toggle button and split
view layout. Added history details dialog with FFmpeg command copy.
Changes:
- internal/ui/mainmenu.go:
* Updated BuildMainMenu() signature to accept sidebar parameters
* Added "☰ History" toggle button to header
* Implemented HSplit layout (20% sidebar, 80% main) when sidebar visible
- main.go:
* Added "sort" import for showHistoryDetails
* Added showHistoryDetails() method to display job details dialog
* Shows timestamps, config, error messages, FFmpeg command
* "Show in Folder" button (only if output file exists)
* "View Log" button (only if log file exists)
* Updated showMainMenu() to build and pass sidebar
* Implemented sidebar toggle that refreshes main menu
The sidebar can be toggled on/off from the main menu, shows history
entries with filtering by status (Completed vs Failed/Cancelled), and
clicking an entry opens a detailed view with all job information and
the ability to copy the FFmpeg command for manual execution.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added history sidebar UI with tabs for completed and failed jobs.
Created reusable UI components and helpers for displaying history entries.
Changes:
- internal/ui/mainmenu.go:
* Added HistoryEntry type definition
* Added BuildHistorySidebar() for main sidebar UI with tabs
* Added buildHistoryList() and buildHistoryItem() helpers
* Added imports for queue and utils packages
- internal/ui/components.go:
* Moved GetStatusColor() and BuildModuleBadge() here as shared functions
* Added queue and utils imports for shared helpers
- internal/ui/queueview.go:
* Updated to use shared GetStatusColor() and BuildModuleBadge()
* Removed duplicate function definitions
- main.go:
* Updated to use ui.HistoryEntry type throughout
* Updated historyConfig, appState, and all methods to use ui.HistoryEntry
The sidebar displays history entries with:
- Status-colored indicators (green/red/orange)
- Module type badges with colors
- Shortened titles and formatted timestamps
- Separate tabs for "Completed" and "Failed" (includes cancelled)
- Empty state messages when no entries exist
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extended the benchmark system to maintain a complete history of all
benchmark runs (up to last 10) with full results for each encoder/preset
combination tested.
Features:
- Stores complete benchmark run data including all test results
- History browser UI to view past benchmark runs
- Click any run to see detailed results for all encoders tested
- Compare performance across different presets and encoders
- Apply recommendations from past benchmarks
- Automatic history limit (keeps last 10 runs)
UI Changes:
- Renamed "Benchmark" button to "Run Benchmark"
- Added "View Results" button to main menu
- New benchmark history view showing all past runs
- Each run displays timestamp, recommended encoder, and test count
- Clicking a run shows full results with all encoder/preset combinations
Data Structure:
- benchmarkRun: stores single test run with all results
- benchmarkConfig: maintains array of benchmark runs
- Saves to ~/.config/VideoTools/benchmark.json
This allows users to review past benchmark results and make informed
decisions about which encoder settings to use by comparing FPS across
all available options on their hardware.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented a full benchmark system that automatically detects available
hardware encoders, tests them with different presets, measures FPS
performance, and recommends optimal settings for the user's system.
Features:
- Automatic test video generation (30s 1080p test pattern)
- Hardware encoder detection (NVENC, QSV, AMF, VideoToolbox)
- Comprehensive encoder testing across multiple presets
- Real-time progress UI with live results
- Performance scoring based on FPS metrics
- Top 10 results display with recommendation
- Config persistence for benchmark results
- One-click apply to use recommended settings
UI Components:
- Benchmark button in main menu header
- Progress view showing current test and results
- Final results view with ranked encoders
- Apply/Close actions for recommendation
Integration:
- Added to main menu between "Benchmark" and "Logs" buttons
- Saves results to ~/.config/VideoTools/benchmark.json
- Comprehensive debug logging for troubleshooting
This allows users to optimize their encoding settings based on their
specific hardware capabilities rather than guessing which encoder
will work best.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- FPS counter in conversion status showing real-time encoding speed
- Job queue now displays FPS, encoding speed (e.g., "1.2x"), and ETA for running conversions
- Copy Comparison button exports side-by-side metadata comparison report
- Auto-compare checkbox in Convert module - automatically loads Compare view after conversion
- Convert Now properly adds job to queue and displays in Job Queue with live stats
- Module badge colors in job queue now match main menu tile colors
- Fixed fullscreen compare window sizing (reduced player dimensions to prevent overflow)
Bug Fixes:
- Fixed queue state management - only one job runs at a time (prevents multiple jobs showing "running")
- Fixed Compare module slot assignment - single video drops now fill empty slot instead of overwriting
- Fixed job queue scroll rubber banding (no longer jumps back to top)
- Enhanced crop detection validation for WMV/AVI formats with dimension clamping and bounds checking
Documentation:
- VT_Player integration notes with API requirements for keyframing and trim features
- LosslessCut feature analysis for Trim module inspiration
- Video metadata guide covering MP4/MKV custom fields and NFO generation
- Trim module design specification
- Compare fullscreen mode documentation
- Updated VIDEO_PLAYER_FORK.md to mark fork as completed
Technical Changes:
- Added state tracking for FPS, speed, and ETA (main.go:197-199)
- Enhanced queue processJobs() to check for running jobs before starting new ones
- Improved Compare module drag-and-drop logic with smart slot assignment (both code paths)
- Added deferred scroll position restoration to prevent UI jumping
- Job queue Config map now carries conversion stats for display
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit includes several improvements:
Queue System Enhancements:
- Improved thread-safety in Add, Remove, Pause, Resume, Cancel operations
- Added PauseAll and ResumeAll methods for batch control
- Added MoveUp and MoveDown methods to reorder queue items
- Better handling of running job cancellation with proper state management
- Improved Copy strategy in List() to prevent race conditions
Convert Module Enhancement:
- Auto-set resolution to 720×480 when NTSC DVD format selected
- Auto-set resolution to 720×576 when PAL DVD format selected
- Auto-set framerate to 29.97fps (30) for NTSC, 25fps for PAL
- Added DVD resolution options to resolution selector dropdown
Display Server Improvements:
- Auto-detect Wayland vs X11 display servers in player controller
- Conditionally apply xdotool window placement (X11 only)
UI Improvements:
- Added Pause All, Resume All, and queue reordering buttons
- Fixed queue counter labeling (completed count display)
Features:
- Add persistent conversion stats bar visible on all screens
- Shows running job progress with live updates
- Displays pending/completed/failed job counts
- Clickable to open queue view
- Add multi-video navigation with Prev/Next buttons
- Load multiple videos for batch queue setup
- Switch between loaded videos to review settings
- Add install script with animated loading spinner
- Add error dialogs with "Copy Error" button for debugging
Improvements:
- Update queue tile to show active/total jobs instead of completed/total
- Fix deadlock in queue callback system (run callbacks in goroutines)
- Improve batch file handling with detailed error reporting
- Fix queue status to always show progress percentage (even at 0%)
- Better error messages for failed video analysis
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a comprehensive job queue system for batch video processing:
- Job queue with priority-based processing
- Queue persistence (saves/restores across app restarts)
- Pause/resume/cancel individual jobs
- Real-time progress tracking
- Queue viewer UI with job management controls
- Clickable queue tile on main menu showing completed/total
- "View Queue" button in convert module
Batch processing features:
- Drag multiple video files to convert tile → auto-add to queue
- Drag folders → recursively scans and adds all videos
- Batch add confirmation dialog
- Supports 14 common video formats
Convert module improvements:
- "Add to Queue" button for queuing single conversions
- "CONVERT NOW" button (renamed for clarity)
- "View Queue" button for quick queue access
Technical implementation:
- internal/queue package with job management
- Job executor with FFmpeg integration
- Progress callbacks for live updates
- Tappable widget component for clickable UI elements
WIP: Queue system functional, tabs feature pending
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Drag-and-Drop on Main Menu:
- Implemented position-based drop detection on main menu module tiles
- Added detectModuleTileAtPosition() to calculate which tile receives the drop
- Modified window drop handler to pass position and route to appropriate module
- Bypasses Fyne's drop event hierarchy limitation where window-level handlers
intercept drops before widgets can receive them
- Only enabled tiles (currently Convert) respond to drops
- Loads video and switches to module automatically
Cover Art Embedding Fixes:
- Fixed FFmpeg exit code 234 error when embedding cover art
- Added explicit PNG codec specification for cover art streams
- Snippet generation: Added `-c✌️1 png` after mapping cover art stream
- Full conversion: Added `-c✌️1 png` for proper MP4 thumbnail encoding
- MP4 containers require attached pictures to be PNG or MJPEG encoded
Embedded Cover Art Extraction:
- Added EmbeddedCoverArt field to videoSource struct
- Extended ffprobe parsing to detect attached_pic disposition
- Automatically extracts embedded thumbnails when loading videos
- Extracted cover art displays in metadata section (168x168)
- Enables round-trip workflow: generate snippet with thumbnail, load snippet
and see the embedded thumbnail displayed
Technical Details:
- Modified handleDrop to accept position parameter
- Added Index and Disposition fields to ffprobe stream parsing
- Cover art streams now excluded from main video stream detection
- Grid layout: 3 columns, ~302px per column, ~122px per row, starts at y=100
- Embedded thumbnails extracted to /tmp/videotools-embedded-cover-*.png
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major refactoring to improve code organization and enhance UI:
Architecture:
- Split monolithic main.go into modular internal/ package structure
- Created internal/logging for centralized logging system
- Created internal/modules for module handler functions
- Created internal/ui for UI components and layouts
- Created internal/utils for shared utility functions
UI Enhancements:
- Implemented rainbow gradient across 8 module buttons (violet→red)
- Increased module button text size to 20 for better readability
- Fixed text centering on module tiles
- Converted Simple/Advanced mode toggle to tabs to save vertical space
- Added vertical scrollbars to prevent UI overflow
- Added metadata copy button (📋) to copy all metadata to clipboard
Video Processing:
- Fixed aspect ratio conversion to default to center-crop behavior
- Added 6 aspect handling modes: Auto, Crop, Letterbox, Pillarbox, Blur Fill, Stretch
- Fixed blur fill to maintain source resolution with padding (no scaling)
- Ensured all FFmpeg filters produce even-numbered dimensions for H.264
Known Issues:
- WMV files still produce FFmpeg error 234 during aspect conversions
(requires codec-specific handling in future update)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>