Implements video transformation features:
- Horizontal flip (mirror effect) using hflip filter
- Vertical flip (upside down) using vflip filter
- Rotation support: 90°, 180°, 270° clockwise using transpose filters
UI additions in Advanced mode:
- New "VIDEO TRANSFORMATIONS" section
- Two checkboxes for flip controls with descriptive labels
- Dropdown selector for rotation angles
- Hint text explaining transformation purpose
Filter implementation:
- Applied after aspect ratio conversion, before frame rate conversion
- Works in both queue-based and direct conversion paths
- Uses FFmpeg standard filters: hflip, vflip, transpose
Addresses user request to add flip/rotation capabilities inspired by Jake's script using -vf hflip.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Check if MSYS2 is already present by looking for the bash executable,
even if winget reports it's already installed. This allows the script
to continue with GCC installation instead of failing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced all emoji characters with standard ASCII status prefixes
to prevent encoding issues on Windows systems:
- ✓/❌ → [OK]/[ERROR]
- ⚠️ → [WARN]
- 📦/🔨/🧹/⬇️/📥 → [INFO]
This ensures the script works correctly on all Windows configurations
regardless of console encoding settings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Batch files interpret unescaped parentheses as block delimiters,
causing "was unexpected at this time" errors and improper branch
execution. All parentheses in echo statements are now escaped with ^.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Capture ERRORLEVEL values immediately after each command execution
to prevent delayed expansion issues in nested conditionals. This
fixes the "was unexpected at this time" error and ensures proper
branch execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced build.bat to automatically detect and offer to install all
required dependencies for users with minimal Windows dev environment:
- Check for winget availability (required for auto-installation)
- Detect and offer to install Git (recommended for development)
- Improved GCC/MinGW detection with fallback instructions
- Better error messages for users without winget
- Graceful degradation when automatic installation is not available
This ensures Jake and other users with just Go installed can run the
build script and get prompted to install everything needed automatically.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed "was unexpected at this time" error by capturing ERRORLEVEL
values into variables before using them in nested if statements.
This is required due to how batch file delayed expansion works.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit includes three critical bug fixes and Windows build improvements:
**Bug Fixes:**
1. **Queue Conversion Progress Tracking** (main.go:1471-1534)
- Enhanced executeConvertJob() to parse FPS, speed, and ETA from FFmpeg output
- Queue jobs now show detailed progress metrics matching direct conversions
- Stats stored in job.Config for display in the conversion stats bar
2. **AMD AMF Hardware Acceleration** (main.go)
- Added "amf" to hardware acceleration options
- Support for h264_amf, hevc_amf, and av1_amf encoders
- Added AMF-specific error detection in FFmpeg output parsing
3. **DVD Format Resolution Forcing** (main.go:1080-1103, 4504-4517)
- Removed automatic resolution forcing when DVD format is selected
- Removed -target parameter usage which was forcing 720×480/720×576
- Resolution now defaults to "Source" unless explicitly changed
- DVD compliance maintained through manual bitrate/GOP/codec parameters
**Windows Build Improvements:**
- Updated build.bat to enable CGO (required for Fyne/OpenGL)
- Added automatic GCC/MinGW-w64 detection and installation
- Automated setup via winget for one-command Windows builds
- Improved error messages with fallback manual instructions
**Documentation:**
- Added comprehensive Windows setup guides
- Created platform.go for future platform-specific code
- Updated .gitignore for Windows build artifacts
All changes tested and working. Ready for production use.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <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>
Fixed thumbnails not displaying:
- Added preview frame generation to Compare module
- Thumbnails now load asynchronously when videos are loaded
- Uses capturePreviewFrames() just like Convert module
- Thumbnails appear after brief generation delay
Added Clear All button:
- Positioned to the right of instructions text
- Clears both File 1 and File 2 slots
- Refreshes view to show empty state
- Low importance styling (not highlighted)
Layout improvements:
- Instructions row now uses Border layout
- Clear All button aligned to the right
- Clean, accessible button placement
Both videos now show thumbnails (240x135) automatically
when loaded, providing visual confirmation of loaded content.
Fixed issue where dragging single videos would overwrite existing data:
Smart slot filling logic:
- Single video dropped: Fills first empty slot (File 1 then File 2)
- If both slots full: Shows dialog asking user to Clear first
- Multiple videos dropped: Fills both slots (replaces existing)
Behavior changes:
1. Drag first video → goes to slot 1
2. Drag second video → goes to slot 2
3. Drag third video → shows "Both Slots Full" message
4. Drag 2+ videos together → replaces both slots
User experience improvements:
- No more accidental overwrites when loading one at a time
- Clear feedback when slots are full
- Can now build comparison by dragging videos individually
- Or drag both at once to start fresh
Main menu drag-and-drop to Compare tile:
- Already working correctly
- Loads both videos sequentially then shows module
- No changes needed to that path
This makes the Compare workflow much more intuitive and prevents
losing loaded video data when adding the second video.
Fixed critical bug where loading second video would overwrite first:
- Changed parallel goroutines to sequential loading
- Load file 1, then file 2, then refresh UI once
- Prevents race condition from multiple showCompareView() calls
- Both files now display correctly side by side
Added action buttons for each file:
- Copy Metadata button: Copies formatted metadata to clipboard
- Clear button: Removes video from slot and refreshes display
- Buttons arranged horizontally: Load | Copy | Clear
- Low importance styling for secondary actions
Changes to drag-and-drop handlers:
- Within Compare module: sequential loading, single refresh
- From main menu: already sequential, no changes needed
- Both paths now work correctly
This fixes the "second file overwrites first" issue and adds
the requested metadata copy and clear functionality.
Added comprehensive documentation on Linux/GNOME compatibility:
Known Issues:
- Double-click titlebar maximize is Fyne framework limitation
- Provided workarounds: Super+Up, maximize button, F11
- Window sizing issues have been fixed
Cross-platform goals:
- Smooth operation on Linux, macOS, Windows
- Single codebase with Fyne framework
- Respect native window manager behaviors
Testing matrix:
- GNOME/Fedora verified
- X11 and Wayland support
- Should work on KDE, XFCE, etc.
Development guidelines:
- Test on both X11 and Wayland
- Consider mouse and keyboard workflows
- Respect window manager tiling
- HiDPI display support
This documentation helps users understand current limitations
and provides context for cross-platform development priorities.
Created comprehensive plan for extracting video player into separate project:
Goals:
- Independent development of player features
- Tighter, more polished video controls
- Reusable component for other projects
- Keep VideoTools focused on video processing
Migration strategy:
1. Extract internal/player to new repo
2. Create clean API interface
3. Update VideoTools to use external package
4. Enhance controls in separate project
Future player improvements:
- Thumbnail preview on seek hover
- Frame-accurate stepping
- Playback speed controls
- Better keyboard shortcuts
- Timeline markers and more
This separation will allow both projects to evolve independently
while keeping the VideoTools codebase lean and focused.
Fixed window resizing issues for better cross-platform behavior:
Convert module video pane:
- Reduced video pane minimum from 460x260 to 320x180
- Removed rigid MinSize on outer container (commented out)
- Removed rigid MinSize on image element
- Set stage minimum to 200x113 (reasonable 16:9 minimum)
- Video pane now scales down allowing smaller windows
Compare module:
- Reduced thumbnail minimum from 320x180 to 240x135
- Reduced metadata scroll minimum from 300x200 to 250x150
- More compact layout allows better window resizing
Benefits:
- Window can now shrink to fit smaller screens
- Better behavior on tiling window managers
- More flexible for cross-platform (Windows, macOS, Linux)
- Content scales intelligently instead of forcing window size
Note: Double-click titlebar maximize is a Fyne framework limitation.
Maximize via window controls or OS shortcuts (F11, Super+Up) works.
Added window centering to improve initial presentation:
- Call w.CenterOnScreen() after setting window size
- Window now opens centered rather than at OS default position
- Maintains existing resizing and maximization support
The window is already maximizable via SetFixedSize(false).
Users can maximize using OS window controls (double-click
titlebar, maximize button, or OS shortcuts like F11/Super+Up).
Prevents long filenames from manipulating window size:
- Truncate filenames longer than 35 characters
- Smart truncation preserves file extension
- Format: "long-filename-na...mp4" instead of wrapping
- Falls back to simple truncation for very long extensions
- Removed text wrapping from labels (no longer needed)
Examples:
- "my-very-long-video-filename.mp4" → "my-very-long-video-fi....mp4"
- "short.mp4" → "short.mp4" (unchanged)
- "filename.mkv" → kept as-is if under 35 chars
This ensures the Compare module labels stay compact and
predictable regardless of filename length.
Resolved UI framing issues where metadata was crushed and not
taking available vertical space:
Layout improvements:
- Used container.NewBorder to make metadata areas expand properly
- Set minimum sizes for scroll containers (300x200)
- Removed outer VScroll - individual metadata areas now scroll
- Grid columns now properly fill available vertical space
- Instructions fixed at top, metadata expands to fill remaining space
Text wrapping fixes:
- Added fyne.TextWrapBreak to file labels
- Prevents long filenames from stretching the window horizontally
- Labels now wrap to multiple lines as needed
Architecture changes:
- Separated file headers (label + button) from content
- Each column uses Border layout: header at top, metadata fills center
- Metadata scroll containers have explicit minimum sizes
- Two-column grid properly distributes horizontal space
The layout now feels more modern with better space utilization
and smooth scrolling within the metadata panels.
Major improvements to Compare module user experience:
- Auto-populate metadata when files are loaded (no Compare button needed)
- Show video thumbnails for both files (320x180)
- Support drag-and-drop onto Compare tile from main menu
- Load up to 2 videos when dropped on Compare tile
- Show dialog if more than 2 videos dropped
- Files loaded via drag show immediately with metadata
Changes to handleModuleDrop:
- Added special handling for Compare module
- Loads videos into compareFile1 and compareFile2 state
- Shows module with files already populated
Changes to buildCompareView:
- Added thumbnail display with dark background placeholders
- Created helper functions: formatMetadata(), loadThumbnail(), updateFile1(), updateFile2()
- Initialize view with any preloaded files
- Removed manual Compare button - metadata shows automatically
- Button handlers now call update functions to refresh display
- Cleaner, more intuitive workflow
This addresses the user feedback that dragging videos onto Compare
didn't load the module, and adds the requested thumbnail previews.
The Compare module now has colored bars at the top and bottom matching
its pink visual identity from the main menu. This creates visual
consistency with the Convert module and strengthens the app's
overall design language.
Changes:
- Added top bar with back button using ui.TintedBar
- Added bottom bar with module color
- Restructured layout to use container.NewBorder
- Made content area scrollable
The colored bars use the module's color (#FF44AA pink) as defined
in modulesList and retrieved via moduleColor().
- Implement drag-and-drop file loading in Compare module
- Accepts up to 2 video files
- Shows dialog if more than 2 videos dropped
- Automatically loads first two videos
- Integrated into global window drop handler
- Enhance metadata display with organized sections
- FILE INFO: path, file size, format
- VIDEO: codec, resolution, aspect ratio, frame rate, bitrate,
pixel format, color space, color range, field order, GOP size
- AUDIO: codec, bitrate, sample rate, channels
- OTHER: duration, SAR, chapters, metadata
- Both file panels now show identical detailed information
Critical Bug Fix:
- H.264 profile and level were being applied globally (-profile:v, -level:v)
- When cover art is present, this affected the PNG encoder stream
- PNG encoder doesn't support H.264 profiles, causing exit code 234
- Error: "Unable to parse option value 'main'" on PNG stream
Solution:
- Use stream-specific specifiers when cover art present
- Apply -profile✌️0 and -level✌️0 instead of -profile:v / -level:v
- This targets only the first video stream (main video)
- PNG cover art stream (1:v) is unaffected
- Fixed in both executeConvertJob() and startConvert()
UI Fix:
- Long output filenames were stretching the settings panel
- Added outputHint.Wrapping = fyne.TextWrapWord
- Filename now wraps properly instead of expanding horizontally
Tested with:
- Video with embedded cover art
- H.264 profile=main encoding
- Long filename conversion
Mark auto-crop, frame rate conversion, and encoder presets as complete in TODO.md.
Add detailed feature descriptions to DONE.md for all three priority features.
This commit enhances the encoder preset selector with detailed information
about speed vs quality trade-offs for each preset option.
Preset Information:
- Ultrafast: ~10x faster than slow, ~30% larger files
- Superfast: ~7x faster than slow, ~20% larger files
- Very Fast: ~5x faster than slow, ~15% larger files
- Faster: ~3x faster than slow, ~10% larger files
- Fast: ~2x faster than slow, ~5% larger files
- Medium: Balanced baseline (default)
- Slow: ~2x slower than medium, ~5-10% smaller (recommended)
- Slower: ~3x slower than medium, ~10-15% smaller
- Very Slow: ~5x slower than medium, ~15-20% smaller
UI Enhancements:
- Dynamic hint label below encoder preset dropdown
- Updates automatically when preset changes
- Visual icons for different speed categories:
- ⚡ Ultrafast/Superfast/Very Fast (prioritize speed)
- ⏩ Faster/Fast (good balance)
- ⚖️ Medium (baseline)
- 🎯 Slow/Slower (recommended for quality)
- 🐌 Very Slow (maximum compression)
Implementation:
- updateEncoderPresetHint() function provides preset details
- Called on preset selection change
- Initialized with current preset on view load
- Positioned directly under preset dropdown for visibility
Benefits:
- Helps users understand encoding time implications
- Shows file size impact of each preset
- Recommends "slow" as best quality/size ratio
- Prevents confusion about preset differences
- Enables informed decisions about encoding settings
Technical:
- All presets already supported by FFmpeg
- No changes to command generation needed
- Works with all video codecs (H.264, H.265, VP9, etc.)
- Preset names match FFmpeg standards