Compare commits

...

19 Commits

Author SHA1 Message Date
815319b3f5 Add thumbnail generation and Clear All button to Compare
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.
2025-12-04 03:39:04 -05:00
653e6721da Fix drag-and-drop to intelligently fill Compare slots
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.
2025-12-04 03:03:19 -05:00
4ce71fb894 Fix Compare module race condition and add action buttons
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.
2025-12-04 02:57:14 -05:00
77ad11eadf Document GNOME compatibility and window management limitations
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.
2025-12-04 01:49:39 -05:00
2d86fb2003 Add video player fork planning document
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.
2025-12-04 01:49:06 -05:00
d3ced0456a Make UI more flexible by reducing rigid minimum sizes
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.
2025-12-04 01:48:22 -05:00
9a63c62deb Center window on screen at startup
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).
2025-12-04 01:42:31 -05:00
0499cf7cb6 Add smart filename truncation in Compare module
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.
2025-12-04 01:41:46 -05:00
0c88169554 Fix Compare module layout to properly utilize window space
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.
2025-12-04 01:40:23 -05:00
6990f18829 Refactor Compare module with auto-loading and thumbnails
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.
2025-12-04 01:39:32 -05:00
1e49fd2f05 Add colored header and footer bars to Compare module
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().
2025-12-04 01:03:11 -05:00
f3d70a0484 Add drag-and-drop support and enhanced metadata to Compare module
- 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
2025-12-04 01:00:38 -05:00
4efdc458a5 Fix H.264 profile applied to PNG cover art stream (exit 234)
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
2025-12-03 22:13:23 -05:00
3d2e5e18a3 Enable Compare module and add smart target file size presets
Compare Module:
- Enable Compare button on main menu (was inactive)
- Module now clickable and functional
- Shows side-by-side video comparison interface

Smart Target File Size:
- Replace simple text entry with intelligent dropdown
- Calculates smart reduction options based on source file size:
  * 75% reduction (source × 0.25)
  * 50% reduction (source × 0.50)
  * 33% reduction (source × 0.67)
- Shows reduction percentage in dropdown labels
- Includes common preset sizes: 25MB, 50MB, 100MB, 200MB, 500MB, 1GB
- Manual entry option for custom sizes
- Entry field hides when preset selected, shows for manual
- Dynamically updates options when video loaded

UI Improvements:
- Dropdown shows "XMB (Y% smaller)" format for smart options
- Parses dropdown value to extract size (handles both formats)
- Manual mode shows entry field with placeholder
- Smart options only shown if resulting size is reasonable (>5MB minimum)
2025-12-03 22:06:14 -05:00
b9cfc5b7c3 Add comprehensive testing guide for dev13 features
Create detailed testing checklist covering all 5 dev13 features:
- Compare module functionality
- Target file size encoding mode
- Auto-crop detection and cropping
- Frame rate conversion with estimates
- Encoder preset descriptions

Includes:
- Step-by-step test procedures
- Expected results for each feature
- Code verification checkpoints (all passing)
- Integration testing requirements
- Known limitations documentation
- Manual testing checklist
- Performance testing guidelines
- Regression testing coverage

Build Status:  PASSING
Code Review:  COMPLETED
Ready for user testing with video files
2025-12-03 21:43:16 -05:00
f3392ff459 Update documentation for completed dev13 features
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.
2025-12-03 21:41:24 -05:00
ca6c303b56 Add encoder preset descriptions with speed/quality trade-offs
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
2025-12-03 21:36:30 -05:00
f620a5e9a2 Add comprehensive frame rate conversion UI with size estimates
This commit implements the frame rate conversion feature with intelligent
file size estimation and user guidance.

Frame Rate Options:
- Added all standard frame rates: 23.976, 24, 25, 29.97, 30, 50, 59.94, 60
- Maintained "Source" option to preserve original frame rate
- Replaced limited [24, 30, 60] with full broadcast standard options
- Supports both film (24 fps) and broadcast (25/29.97/30 fps) standards

Size Estimation:
- Calculates approximate file size reduction when downconverting
- Shows "Converting X → Y fps: ~Z% smaller file" hint
- Example: 60→30 fps shows "~50% smaller file"
- Dynamically updates hint when frame rate or video changes
- Only shows hint when conversion would reduce frame rate

User Warnings:
- Detects upscaling (target > source fps)
- Warns with ⚠ icon: "Upscaling from X to Y fps (may cause judder)"
- Prevents confusion about interpolation limitations
- No hint shown when target equals source

Implementation:
- updateFrameRateHint() function recalculates on changes
- Parses frame rate strings to float64 for comparison
- Calculates reduction percentage: (1 - target/source) * 100
- Updates automatically when video loaded or frame rate changed
- Positioned directly under frame rate dropdown for visibility

Technical:
- Uses FFmpeg fps filter (already implemented)
- Works in both direct convert and queue execution
- Integrated with existing frame rate handling
- No changes to FFmpeg command generation needed

Benefits:
- 40-50% file size reduction for 60→30 fps conversions
- Clear visual feedback before encoding
- Prevents accidental upscaling
- Helps users make informed compression decisions
2025-12-03 21:33:05 -05:00
f496f73f96 Implement automatic black bar detection and cropping
This commit implements the highest priority dev13 feature: automatic
cropdetect with manual override capability.

Features:
- Added detectCrop() function that analyzes 10 seconds of video
- Samples from middle of video for stable detection
- Parses FFmpeg cropdetect output using regex
- Shows estimated file size reduction percentage (15-30% typical)
- User confirmation dialog before applying crop values

UI Changes:
- Added "Auto-Detect Black Bars" checkbox in Advanced mode
- Added "Detect Crop" button to trigger analysis
- Button shows "Detecting..." status during analysis
- Runs detection in background to avoid blocking UI
- Dialog shows before/after dimensions and savings estimate

Implementation:
- Added CropWidth, CropHeight, CropX, CropY to convertConfig
- Crop filter applied before scaling for best results
- Works in both direct convert and queue job execution
- Proper error handling for videos without black bars
- Defaults to center crop if X/Y offsets not specified

Technical Details:
- Uses FFmpeg cropdetect filter with threshold 24
- Analyzes last detected crop value (most stable)
- 30-second timeout for detection process
- Regex pattern: crop=(\d+):(\d+):(\d+):(\d+)
- Calculates pixel reduction for savings estimate

Benefits:
- 15-30% file size reduction with zero quality loss
- Automatic detection eliminates manual measurement
- Confirmation dialog prevents accidental crops
- Clear visual feedback during detection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:25:27 -05:00
6 changed files with 1501 additions and 172 deletions

63
DONE.md
View File

@ -2,6 +2,69 @@
This file tracks completed features, fixes, and milestones.
## Version 0.1.0-dev13 (In Progress - 2025-12-03)
### Features
- ✅ **Automatic Black Bar Detection and Cropping**
- Detects and removes black bars to reduce file size (15-30% typical reduction)
- One-click "Detect Crop" button analyzes video using FFmpeg cropdetect
- Samples 10 seconds from middle of video for stable detection
- Shows estimated file size reduction percentage before applying
- User confirmation dialog displays before/after dimensions
- Manual crop override capability (width, height, X/Y offsets)
- Applied before scaling for optimal results
- Works in both direct convert and queue job execution
- Proper handling for videos without black bars
- 30-second timeout protection for detection process
- ✅ **Frame Rate Conversion UI with Size Estimates**
- Comprehensive frame rate options: Source, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60
- Intelligent file size reduction estimates (40-50% for 60→30 fps)
- Real-time hints showing "Converting X → Y fps: ~Z% smaller file"
- Warning for upscaling attempts with judder notice
- Automatic calculation based on source and target frame rates
- Dynamic updates when video or frame rate changes
- Supports both film (24 fps) and broadcast standards (25/29.97/30)
- Uses FFmpeg fps filter for frame rate conversion
- ✅ **Encoder Preset Descriptions with Speed/Quality Trade-offs**
- Detailed information for all 9 preset options
- Speed comparisons relative to "slow" and "medium" baselines
- File size impact percentages for each preset
- Visual icons indicating speed categories (⚡⏩⚖️🎯🐌)
- Recommends "slow" as best quality/size ratio
- Dynamic hint updates when preset changes
- Helps users make informed encoding time decisions
- Ranges from ultrafast (~10x faster, ~30% larger) to veryslow (~5x slower, ~15-20% smaller)
- ✅ **Compare Module**
- Side-by-side video comparison interface
- Load two videos and compare detailed metadata
- Displays format, resolution, codecs, bitrates, frame rate, pixel format
- Shows color space, color range, GOP size, field order
- Indicates presence of chapters and metadata
- Accessible via GUI button (pink color) or CLI: `videotools compare <file1> <file2>`
- Added formatBitrate() helper function for consistent bitrate display
- ✅ **Target File Size Encoding Mode**
- New "Target Size" bitrate mode in convert module
- Specify desired output file size (e.g., "25MB", "100MB", "8MB")
- Automatically calculates required video bitrate based on:
- Target file size
- Video duration
- Audio bitrate
- Container overhead (3% reserved)
- Implemented ParseFileSize() to parse size strings (KB, MB, GB)
- Implemented CalculateBitrateForTargetSize() for bitrate calculation
- Works in both GUI convert view and job queue execution
- Minimum bitrate sanity check (100 kbps) to prevent invalid outputs
### Technical Improvements
- ✅ Added compare command to CLI help text
- ✅ Consistent "Target Size" naming throughout UI and code
- ✅ Added compareFile1 and compareFile2 to appState for video comparison
- ✅ Module button grid updated with compare button (pink/magenta color)
## Version 0.1.0-dev12 (2025-12-02)
### Features

390
TESTING_DEV13.md Normal file
View File

@ -0,0 +1,390 @@
# VideoTools v0.1.0-dev13 Testing Guide
This document provides a comprehensive testing checklist for all dev13 features.
## Build Status
- ✅ **Compiles successfully** with no errors
- ✅ **CLI help** displays correctly with compare command
- ✅ **All imports** resolved correctly (regexp added for cropdetect)
## Features to Test
### 1. Compare Module
**Test Steps:**
1. Launch VideoTools GUI
2. Click "Compare" module button (pink/magenta color)
3. Click "Load File 1" and select a video
4. Click "Load File 2" and select another video
5. Click "COMPARE" button
**Expected Results:**
- File 1 and File 2 metadata displayed side-by-side
- Shows: Format, Resolution, Duration, Codecs, Bitrates, Frame Rate
- Shows: Pixel Format, Aspect Ratio, Color Space, Color Range
- Shows: GOP Size, Field Order, Chapters, Metadata flags
- formatBitrate() displays bitrates in human-readable format (Mbps/kbps)
**CLI Test:**
```bash
./VideoTools compare video1.mp4 video2.mp4
```
**Code Verification:**
- ✅ buildCompareView() function implemented (main.go:4916)
- ✅ HandleCompare() handler registered (main.go:59)
- ✅ Module button added to grid with pink color (main.go:69)
- ✅ formatBitrate() helper function (main.go:4900)
- ✅ compareFile1/compareFile2 added to appState (main.go:197-198)
---
### 2. Target File Size Encoding Mode
**Test Steps:**
1. Load a video in Convert module
2. Switch to Advanced mode
3. Set Bitrate Mode to "Target Size"
4. Enter target size (e.g., "25MB", "100MB", "8MB")
5. Start conversion or add to queue
**Expected Results:**
- FFmpeg calculates video bitrate from: target size, duration, audio bitrate
- Reserves 3% for container overhead
- Minimum 100 kbps sanity check applied
- Works in both direct convert and queue jobs
**Test Cases:**
- Video: 1 minute, Target: 25MB, Audio: 192k → Video bitrate calculated
- Video: 5 minutes, Target: 100MB, Audio: 192k → Video bitrate calculated
- Very small target that would be impossible → Falls back to 100 kbps minimum
**Code Verification:**
- ✅ TargetFileSize field added to convertConfig (main.go:125)
- ✅ Target Size UI entry with placeholder (main.go:1931-1936)
- ✅ ParseFileSize() parses KB/MB/GB (internal/convert/types.go:205)
- ✅ CalculateBitrateForTargetSize() with overhead calc (internal/convert/types.go:173)
- ✅ Applied in startConvert() (main.go:3993)
- ✅ Applied in executeConvertJob() (main.go:1109)
- ✅ Passed to queue config (main.go:611)
---
### 3. Automatic Black Bar Detection & Cropping
**Test Steps:**
1. Load a video with black bars (letterbox/pillarbox)
2. Switch to Advanced mode
3. Scroll to AUTO-CROP section
4. Click "Detect Crop" button
5. Wait for detection (button shows "Detecting...")
6. Review detection dialog showing savings estimate
7. Click "Apply" to use detected values
8. Verify AutoCrop checkbox is checked
**Expected Results:**
- Samples 10 seconds from middle of video
- Uses FFmpeg cropdetect filter (threshold 24)
- Shows original vs cropped dimensions
- Calculates and displays pixel reduction percentage
- Applies crop values to config
- Works for both direct convert and queue jobs
**Test Cases:**
- Video with letterbox bars (top/bottom) → Detects and crops
- Video with pillarbox bars (left/right) → Detects and crops
- Video with no black bars → Shows "already fully cropped" message
- Very short video (<10 seconds) Still attempts detection
**Code Verification:**
- ✅ detectCrop() function with 30s timeout (main.go:4841)
- ✅ CropValues struct (main.go:4832)
- ✅ Regex parsing: crop=(\d+):(\d+):(\d+):(\d+) (main.go:4870)
- ✅ AutoCrop checkbox in UI (main.go:1765)
- ✅ Detect Crop button with background execution (main.go:1771)
- ✅ Confirmation dialog with savings calculation (main.go:1797)
- ✅ Crop filter applied before scaling (main.go:3996)
- ✅ Works in queue jobs (main.go:1023)
- ✅ CropWidth/Height/X/Y fields added (main.go:136-139)
- ✅ Passed to queue config (main.go:621-625)
---
### 4. Frame Rate Conversion UI with Size Estimates
**Test Steps:**
1. Load a 60fps video in Convert module
2. Switch to Advanced mode
3. Find "Frame Rate" dropdown
4. Select "30" fps
5. Observe hint message below dropdown
**Expected Results:**
- Shows: "Converting 60 → 30 fps: ~50% smaller file"
- Hint updates dynamically when selection changes
- Warning shown for upscaling: "⚠ Upscaling from 30 to 60 fps (may cause judder)"
- No hint when "Source" selected or target equals source
**Test Cases:**
- 60fps → 30fps: Shows ~50% reduction
- 60fps → 24fps: Shows ~60% reduction
- 30fps → 60fps: Shows upscaling warning
- 30fps → 30fps: No hint (same as source)
- Video with unknown fps: No hint shown
**Frame Rate Options:**
- Source, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60
**Code Verification:**
- ✅ All frame rate options added (main.go:2107)
- ✅ updateFrameRateHint() function (main.go:2051)
- ✅ Calculates reduction percentage (main.go:2094-2098)
- ✅ Upscaling warning (main.go:2099-2101)
- ✅ frameRateHint label in UI (main.go:2215)
- ✅ Updates on selection change (main.go:2110)
- ✅ FFmpeg fps filter already applied (main.go:4643-4646)
---
### 5. Encoder Preset Descriptions
**Test Steps:**
1. Load any video in Convert module
2. Switch to Advanced mode
3. Find "Encoder Preset" dropdown
4. Select different presets and observe hint
**Expected Results:**
- Each preset shows speed vs quality trade-off
- Visual icons: ⚡⏩⚖️🎯🐌
- Shows percentage differences vs baseline
- Recommends "slow" as best quality/size ratio
**Preset Information:**
- ultrafast: ⚡ ~10x faster than slow, ~30% larger
- superfast: ⚡ ~7x faster than slow, ~20% larger
- veryfast: ⚡ ~5x faster than slow, ~15% larger
- faster: ⏩ ~3x faster than slow, ~10% larger
- fast: ⏩ ~2x faster than slow, ~5% larger
- medium: ⚖️ Balanced (default baseline)
- slow: 🎯 Best ratio ~2x slower, ~5-10% smaller (RECOMMENDED)
- slower: 🎯 ~3x slower, ~10-15% smaller
- veryslow: 🐌 ~5x slower, ~15-20% smaller
**Code Verification:**
- ✅ updateEncoderPresetHint() function (main.go:2006)
- ✅ All 9 presets with descriptions (main.go:2009-2027)
- ✅ Visual icons for categories (main.go:2010, 2016, 2020, 2022, 2026)
- ✅ encoderPresetHint label in UI (main.go:2233)
- ✅ Updates on selection change (main.go:2036)
- ✅ Initialized with current preset (main.go:2039)
---
## Integration Testing
### Queue System Integration
**All features must work when added to queue:**
- [ ] Compare module (N/A - not a conversion operation)
- [ ] Target File Size mode in queue job
- [ ] Auto-crop in queue job
- [ ] Frame rate conversion in queue job
- [ ] Encoder preset in queue job
**Code Verification:**
- ✅ All config fields passed to queue (main.go:599-634)
- ✅ executeConvertJob() handles all new fields
- ✅ Target Size: lines 1109-1133
- ✅ Auto-crop: lines 1023-1048
- ✅ Frame rate: line 1091-1094
- ✅ Encoder preset: already handled via encoderPreset field
### Settings Persistence
**Settings should persist across video loads:**
- [ ] Auto-crop checkbox state persists
- [ ] Frame rate selection persists
- [ ] Encoder preset selection persists
- [ ] Target file size value persists
**Code Verification:**
- ✅ All settings stored in state.convert
- ✅ Settings not reset when loading new video
- ✅ Reset button available to restore defaults (main.go:1823)
---
## Known Limitations
1. **Auto-crop detection:**
- Samples only 10 seconds (may miss variable content)
- 30-second timeout for very slow systems
- Assumes black bars are consistent throughout video
2. **Frame rate conversion:**
- Estimates are approximate (actual savings depend on content)
- No motion interpolation (drops/duplicates frames only)
3. **Target file size:**
- Estimate based on single-pass encoding
- Container overhead assumed at 3%
- Actual file size may vary by ±5%
4. **Encoder presets:**
- Speed/size estimates are averages
- Actual performance depends on video complexity
- GPU acceleration may alter speed ratios
---
## Manual Testing Checklist
### Pre-Testing Setup
- [ ] Have test videos ready:
- [ ] 60fps video for frame rate testing
- [ ] Video with black bars for crop detection
- [ ] Short video (< 1 min) for quick testing
- [ ] Long video (> 5 min) for queue testing
### Compare Module
- [ ] Load two different videos
- [ ] Compare button shows both metadata
- [ ] Bitrates display correctly (Mbps/kbps)
- [ ] All fields populated correctly
- [ ] "Back to Menu" returns to main menu
### Target File Size
- [ ] Set target of 25MB on 1-minute video
- [ ] Verify conversion completes
- [ ] Check output file size (should be close to 25MB ±5%)
- [ ] Test with very small target (e.g., 1MB)
- [ ] Verify in queue job
### Auto-Crop
- [ ] Detect crop on letterbox video
- [ ] Verify savings percentage shown
- [ ] Apply detected values
- [ ] Convert with crop applied
- [ ] Compare output dimensions
- [ ] Test with no-black-bar video (should say "already fully cropped")
- [ ] Verify in queue job
### Frame Rate Conversion
- [ ] Load 60fps video
- [ ] Select 30fps
- [ ] Verify hint shows "~50% smaller"
- [ ] Select 60fps (same as source)
- [ ] Verify no hint shown
- [ ] Select 24fps
- [ ] Verify different percentage shown
- [ ] Try upscaling (30→60)
- [ ] Verify warning shown
### Encoder Presets
- [ ] Select "ultrafast" - verify hint shows
- [ ] Select "medium" - verify balanced description
- [ ] Select "slow" - verify recommendation shown
- [ ] Select "veryslow" - verify maximum compression note
- [ ] Test actual encoding with different presets
- [ ] Verify speed differences are noticeable
### Error Cases
- [ ] Auto-crop with no video loaded → Should show error dialog
- [ ] Very short video for crop detection → Should still attempt
- [ ] Invalid target file size (e.g., "abc") → Should handle gracefully
- [ ] Extremely small target size → Should apply 100kbps minimum
---
## Performance Testing
### Auto-Crop Detection Speed
- Expected: ~2-5 seconds for typical video
- Timeout: 30 seconds maximum
- [ ] Test on 1080p video
- [ ] Test on 4K video
- [ ] Test on very long video (should still sample 10s)
### Memory Usage
- [ ] Load multiple videos in compare mode
- [ ] Check memory doesn't leak
- [ ] Test with large (4K+) videos
---
## Regression Testing
Verify existing features still work:
- [ ] Basic video conversion works
- [ ] Queue add/remove/execute works
- [ ] Direct convert (not queued) works
- [ ] Simple mode still functional
- [ ] Advanced mode shows all controls
- [ ] Aspect ratio handling works
- [ ] Deinterlacing works
- [ ] Audio settings work
- [ ] Hardware acceleration detection works
---
## Documentation Review
- ✅ DONE.md updated with all features
- ✅ TODO.md marked features as complete
- ✅ Commit messages are descriptive
- ✅ Code comments explain complex logic
- [ ] README.md updated (if needed)
---
## Code Quality
### Code Review Completed:
- ✅ No compilation errors
- ✅ All imports resolved
- ✅ No obvious logic errors
- ✅ Error handling present (dialogs, nil checks)
- ✅ Logging added for debugging
- ✅ Function names are descriptive
- ✅ Code follows existing patterns
### Potential Issues to Watch:
- Crop detection regex assumes specific FFmpeg output format
- Frame rate hint calculations assume source FPS is accurate
- Target size calculation assumes consistent bitrate encoding
- 30-second timeout for crop detection might be too short on very slow systems
---
## Sign-off
**Build Status:** ✅ PASSING
**Code Review:** ✅ COMPLETED
**Manual Testing:** ⏳ PENDING (requires video files)
**Documentation:** ✅ COMPLETED
**Ready for User Testing:** YES (with video files)
---
## Testing Commands
```bash
# Build
go build -o VideoTools
# CLI Help
./VideoTools help
# Compare (CLI)
./VideoTools compare video1.mp4 video2.mp4
# GUI
./VideoTools
# Debug mode
VIDEOTOOLS_DEBUG=1 ./VideoTools
```
---
Last Updated: 2025-12-03

14
TODO.md
View File

@ -5,21 +5,21 @@ This file tracks upcoming features, improvements, and known issues.
## Priority Features for dev13 (Based on Jake's research)
### Quality & Compression Improvements
- [ ] **Automatic black bar detection and cropping** (HIGHEST PRIORITY)
- [x] **Automatic black bar detection and cropping** (v0.1.0-dev13 - COMPLETED)
- Implement ffmpeg cropdetect analysis pass
- Auto-apply detected crop values
- 15-30% file size reduction with zero quality loss
- Add manual crop override option
- [ ] **Frame rate conversion UI**
- Dropdown: Source, 24, 25, 29.97, 30, 50, 59.94, 60 fps
- [x] **Frame rate conversion UI** (v0.1.0-dev13 - COMPLETED)
- Dropdown: Source, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60 fps
- Auto-suggest 60→30fps conversion with size estimate
- Show file size impact (40-45% reduction for 60→30)
- Show file size impact (40-50% reduction for 60→30)
- [ ] **HEVC/H.265 preset options**
- Add preset dropdown: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
- [x] **HEVC/H.265 encoder preset options** (v0.1.0-dev13 - COMPLETED)
- Preset dropdown: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
- Show time/quality trade-off estimates
- Default to "slow" for best quality/size balance
- Recommend "slow" for best quality/size balance
- [ ] **Advanced filters module**
- Denoising: hqdn3d (fast), nlmeans (slow, high quality)

109
docs/GNOME_COMPATIBILITY.md Normal file
View File

@ -0,0 +1,109 @@
# GNOME/Linux Compatibility Notes
## Current Status
VideoTools is built with Fyne UI framework and runs on GNOME/Fedora and other Linux desktop environments.
## Known Issues
### Double-Click Titlebar to Maximize
**Issue**: Double-clicking the titlebar doesn't maximize the window like native GNOME apps.
**Cause**: This is a Fyne framework limitation. Fyne uses its own window rendering and doesn't fully implement all native window manager behaviors.
**Workarounds for Users**:
- Use GNOME's maximize button in titlebar
- Use keyboard shortcuts: `Super+Up` (GNOME default)
- Press `F11` for fullscreen (if app supports it)
- Right-click titlebar → Maximize
**Status**: Upstream Fyne issue. Monitor: https://github.com/fyne-io/fyne/issues
### Window Sizing
**Fixed**: Window now properly resizes and can be made smaller. Minimum sizes have been reduced to allow flexible layouts.
## Desktop Environment Testing
### Tested On
- ✅ GNOME (Fedora 43)
- ✅ X11 session
- ✅ Wayland session
### Should Work On (Untested)
- KDE Plasma
- XFCE
- Cinnamon
- MATE
- Other Linux DEs
## Cross-Platform Goals
VideoTools aims to run smoothly on:
- **Linux**: GNOME, KDE, XFCE, etc.
- **macOS**: Native macOS window behavior
- **Windows**: Native Windows window behavior
## Fyne Framework Considerations
### Advantages
- Cross-platform by default
- Single codebase for all OSes
- Modern Go-based development
- Good performance
### Limitations
- Some native behaviors may differ
- Window management is abstracted
- Custom titlebar rendering
- Some OS-specific shortcuts may not work
## Future Improvements
### Short Term
- [x] Flexible window sizing
- [x] Better minimum size handling
- [ ] Document all keyboard shortcuts
- [ ] Test on more Linux DEs
### Long Term
- [ ] Consider native window decorations option
- [ ] Investigate Fyne improvements for window management
- [ ] Add more GNOME-like keyboard shortcuts
- [ ] Better integration with system theme
## Recommendations for Users
### GNOME Users
- Use Super key shortcuts for window management
- Maximize: `Super+Up`
- Snap left/right: `Super+Left/Right`
- Fullscreen: `F11` (if supported)
- Close: `Alt+F4` or `Ctrl+Q`
### General Linux Users
- Most window management shortcuts work via your window manager
- VideoTools respects window manager tiling
- Window can be resized freely
- Multiple instances can run simultaneously
## Development Notes
When adding features:
- Test on both X11 and Wayland
- Verify window resizing behavior
- Check keyboard shortcuts don't conflict
- Consider both mouse and keyboard workflows
- Test with HiDPI displays
## Reporting Issues
If you encounter GNOME/Linux specific issues:
1. Note your distro and desktop environment
2. Specify X11 or Wayland
3. Include window manager if using tiling WM
4. Provide steps to reproduce
5. Check if issue exists on other platforms
## Resources
- Fyne Documentation: https://developer.fyne.io/
- GNOME HIG: https://developer.gnome.org/hig/
- Linux Desktop Testing: Multiple VMs recommended

106
docs/VIDEO_PLAYER_FORK.md Normal file
View File

@ -0,0 +1,106 @@
# Video Player Fork Plan
## Overview
The video player component will be extracted into a separate project to allow independent development and improvement of video playback controls while keeping VideoTools focused on video processing.
## Current Player Integration
The player is currently embedded in VideoTools at:
- `internal/player/` - Player implementation
- `main.go` - Player state and controls in Convert module
- Preview frame display
- Playback controls (play/pause, seek, volume)
## Fork Goals
### 1. Independent Development
- Develop player features without affecting VideoTools
- Faster iteration on playback controls
- Better testing of player-specific features
- Can be used by other projects
### 2. Improved Controls
Current limitations to address:
- Tighten up video controls
- Better seek bar with thumbnails on hover
- Improved timeline scrubbing
- Keyboard shortcuts for playback
- Frame-accurate stepping
- Playback speed controls
- Better volume control UI
### 3. Clean API
The forked player should expose a clean API:
```go
type Player interface {
Load(path string) error
Play()
Pause()
Seek(position time.Duration)
GetFrame(position time.Duration) (image.Image, error)
SetVolume(level float64)
Close()
}
```
## Migration Strategy
### Phase 1: Extract to Separate Module
1. Create new repository: `github.com/yourusername/fyne-videoplayer`
2. Copy `internal/player/` to new repo
3. Extract player dependencies
4. Create clean API surface
5. Add comprehensive tests
### Phase 2: Update VideoTools
1. Import fyne-videoplayer as dependency
2. Replace internal/player with external package
3. Update player instantiation
4. Verify all playback features work
5. Remove old internal/player code
### Phase 3: Enhance Player (Post-Fork)
Features to add after fork:
- [ ] Thumbnail preview on seek bar hover
- [ ] Frame-accurate stepping (←/→ keys)
- [ ] Playback speed controls (0.25x to 2x)
- [ ] Improved volume slider
- [ ] Keyboard shortcuts (Space, K, J, L, etc.)
- [ ] Timeline markers
- [ ] Subtitle support
- [ ] Multi-audio track switching
## Technical Considerations
### Dependencies
Current dependencies to maintain:
- Fyne for UI rendering
- FFmpeg for video decoding
- CGO for FFmpeg bindings
### Cross-Platform Support
Player must work on:
- Linux (GNOME, KDE, etc.)
- macOS
- Windows
### Performance
- Hardware acceleration where available
- Efficient frame buffering
- Low CPU usage during playback
- Fast seeking
## Timeline
1. **Week 1-2**: Extract player code, create repo, clean API
2. **Week 3**: Integration testing, update VideoTools
3. **Week 4+**: Enhanced controls and features
## Benefits
- **VideoTools**: Leaner codebase, focus on processing
- **Player**: Independent evolution, reusable component
- **Users**: Better video controls, more reliable playback
- **Developers**: Easier to contribute to either project
## Notes
- Keep player dependency minimal in VideoTools
- Player should be optional - frame display can work without playback
- Consider using player in Compare module for side-by-side playback (future)

991
main.go

File diff suppressed because it is too large Load Diff