Changed thumbnail module to match convert module behavior with two
action buttons:
GENERATE NOW (High Importance):
- Adds job to queue and starts it immediately
- Runs right away if queue is idle
- Queues for later if jobs are running
- Shows "Thumbnail generation started!" message
Add to Queue (Medium Importance):
- Adds job to queue without starting
- Allows queuing multiple jobs
- Shows "Thumbnail job added to queue!" message
Implementation:
- Refactored job creation into createThumbJob() helper function
- Both buttons use same job creation logic
- Generate Now auto-starts queue if not running
- Follows same pattern as convert module
Benefits:
- Immediate generation when queue is idle
- Queue multiple jobs without starting
- Consistent UX with convert module
- Clear user feedback on action taken
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed the exit 234 error when generating individual thumbnails by
disabling the timestamp overlay feature which was causing FFmpeg
font-related failures on some systems.
Changes:
- ShowTimestamp: false (was true)
- ShowMetadata: only true for contact sheets (was always true)
The timestamp overlay was causing issues because:
1. DejaVu Sans Mono font might not be available on all systems
2. FFmpeg exits with code 234 when drawtext filter fails
3. Individual thumbnails don't need timestamp overlays anyway
Contact sheets still get metadata headers, which is the main use case
for showing video information on thumbnails.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed Thumbnail Count Issue:
- Changed frame selection from hardcoded 30fps to timestamp-based
- Now uses gte(t,timestamp) filter for accurate frame selection
- This fixes the issue where 5x8 grid only generated 34 instead of 40 thumbnails
Improved Contact Sheet Display:
- Reduced thumbnail width from 320px to 200px for better window fit
- Changed background color from black to app theme (#0B0F1A)
- Contact sheets now match the VideoTools dark blue theme
Added Viewing Capability:
- New "View Results" button in thumbnail module
- Contact sheet mode: Shows image in full-screen dialog (900x700)
- Individual mode: Opens thumbnail folder in file manager
- Button checks if output exists before showing
- Provides user-friendly messages when no results found
Benefits:
- Correct number of thumbnails generated for any grid size
- Contact sheets fit better in display window
- Visual consistency with app theme
- Easy access to view generated results within the app
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added full job queue integration for thumbnail generation:
Job Queue Integration:
- Implemented executeThumbJob() to handle thumbnail generation in queue
- Changed "Generate Thumbnails" to "Add to Queue" button
- Added "View Queue" button to thumbnail module
- Removed direct generation code in favor of queue system
Progress Tracking:
- Jobs now show in queue with progress bar
- Contact sheet mode: shows grid dimensions in description
- Individual mode: shows count and width in description
- Job title: "Thumbnails: {filename}"
Benefits:
- Real-time progress tracking via queue progress bar
- Can queue multiple thumbnail jobs
- Access queue from thumbnail screen
- Consistent with other modules (convert, merge, snippet)
- Background processing without blocking UI
The thumbnail module now uses the same job queue system as other
modules, providing progress tracking and background processing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed the total thumbnails label to update in real-time when adjusting
columns or rows sliders in contact sheet mode.
Changes:
- Created totalLabel before sliders so both callbacks can access it
- Both column and row slider OnChanged callbacks now update the total
- Total recalculates as: columns × rows on each slider change
The total now updates immediately as you adjust the grid dimensions,
providing instant feedback on how many thumbnails will be generated.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed Issues:
- Exit 234 error: Added font parameter to drawtext filter for individual
thumbnails (was missing, causing FFmpeg to fail)
- Output directory: Changed from temp to video's directory, creating a
folder named "{video}_thumbnails" next to the source file
New Features:
- Added video preview window to thumbnail module (640x360)
- Split layout: preview on left (55%), settings on right (45%)
- Preview uses same buildVideoPane as other modules for consistency
The thumbnail module now has a proper preview window for reviewing
the loaded video before generating thumbnails, and outputs are saved
in a logical location next to the source file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated FFmpeg drawtext filter to use DejaVu Sans Mono for metadata
text on contact sheets. This matches the monospace font style used
throughout the VideoTools UI.
DejaVu Sans Mono is widely available across Linux, macOS, and Windows,
ensuring consistent appearance across platforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed snippet extraction to use stream copy instead of re-encoding:
- Removed all convert config and encoding logic
- Now uses `-c copy` to copy all streams without re-encoding
- Uses same file extension as source for container compatibility
- Much faster extraction with no quality loss
- Updated job description to indicate "source settings"
This makes snippet generation instant instead of requiring full re-encode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented metadata header rendering on contact sheets showing:
- Filename and file size
- Video resolution and duration
Uses FFmpeg pad and drawtext filters to create an 80px header area
with white text on black background.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
New Features:
- Thumbnail extraction package with FFmpeg integration
- Individual thumbnails or contact sheet generation
- Configurable thumbnail count (3-50 thumbnails)
- Adjustable thumbnail width (160-640 pixels)
- Contact sheet mode with customizable grid (2-10 columns/rows)
- Timestamp overlay on thumbnails
- Auto-open generated thumbnails folder
Technical Implementation:
- internal/thumbnail package with generator
- FFmpeg-based frame extraction
- Video duration and dimension detection
- Aspect ratio preservation
- JPEG quality control
- PNG lossless option support
UI Features:
- Thumbnail module in main menu (Orange tile)
- Load video via file picker
- Real-time configuration sliders
- Contact sheet toggle with grid controls
- Generate button with progress feedback
- Success dialog with folder open option
Integration:
- Added to module routing system
- State management for thumb module
- Proper Fyne threading with DoFromGoroutine
- Cross-platform folder opening support
Module is fully functional and ready for testing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features added:
- Auto-detection in Inspect module: runs QuickAnalyze automatically when video is loaded
- Interlacing results display in Inspect metadata panel
- Deinterlace preview generation: side-by-side comparison button in Convert view
- Analyze button integration in Simple menu deinterlacing section
- Auto-apply deinterlacing settings when recommended
The Inspect module now automatically analyzes videos for interlacing when loaded via:
- Load button
- Drag-and-drop to main menu tile
- Drag-and-drop within Inspect view
Results appear directly in the metadata panel with full detection details.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Created core interlacing detection system using FFmpeg's idet filter.
Features:
- Analyze videos for interlacing using FFmpeg idet filter
- Parse TFF, BFF, Progressive, and Undetermined frame counts
- Calculate interlacing percentage and confidence level
- Determine field order (TFF/BFF/Mixed/Progressive)
- Generate recommendations for deinterlacing
- Quick analysis mode (first 500 frames) for speed
- Full video analysis option
- Preview generation: deinterlaced frame or side-by-side comparison
Detection Results include:
- Status: Progressive / Interlaced / Mixed Content
- Interlacing %: Portion of frames that are interlaced
- Field Order: Top Field First, Bottom Field First, or Unknown
- Confidence: High/Medium/Low based on undetermined frames
- Recommendation: Human-readable guidance
- Suggested filter: yadif, bwdif, etc.
Next: UI integration in Convert and Inspect modules
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major features in this release:
1. Fixed merge job progress reporting
- Progress counter was jumping to 100% immediately due to incorrect
time unit conversion (microseconds vs milliseconds)
- Now shows accurate real-time progress throughout merge operations
2. Hardware encoder benchmarking system
- Automatic test video generation (30s 1080p test pattern)
- Detects available hardware encoders (NVENC, QSV, AMF, VideoToolbox)
- Tests all available encoders with multiple presets
- Measures FPS performance and ranks results
- Provides optimal encoder recommendation for user's hardware
- Real-time progress tracking with live results display
3. Benchmark history tracking
- Stores up to 10 most recent benchmark runs
- Browse past benchmark results with detailed comparisons
- View all encoder/preset combinations tested in each run
- Compare performance across different presets and encoders
- Apply recommendations from any past benchmark
- Persistent storage in ~/.config/VideoTools/benchmark.json
UI improvements:
- "Run Benchmark" button in main menu
- "View Results" button to browse benchmark history
- Live progress view showing current test and results
- Comprehensive results view with all encoder data
- Fixed merge module file list to use full vertical space
Bug fixes:
- Fixed merge progress calculation (microseconds issue)
- Fixed Fyne threading errors in benchmark UI updates
- Fixed progress bar percentage display (0-100 range)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The progress bar was configured with Max=100 but we were setting
values in the 0.0-1.0 range, causing it to always show ~0%.
Fixed by multiplying the percentage by 100 before setting the value,
so 4/22 = 0.18 becomes 18% instead of 0.18%.
Also fixed SetComplete() to set 100.0 instead of 1.0.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
All UI updates from the benchmark goroutine were causing threading
errors because they weren't wrapped in DoFromGoroutine. Fixed:
- UpdateProgress: progress bar and label updates
- AddResult: adding result cards to the display
- SetComplete: final status updates
These methods are called from background goroutines running the
benchmark tests, so all UI updates must be dispatched to the main
thread using fyne.CurrentApp().Driver().DoFromGoroutine().
🤖 Generated with [Claude Code](https://claude.com/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>
The issue was that FFmpeg's out_time_ms field is actually in microseconds
(not milliseconds despite the name). We were dividing by 1,000 when we
should have been dividing by 1,000,000 to convert to seconds.
This caused the progress calculation to be off by 1000x, making it
immediately jump to 100% even though the job was just starting.
Also added comprehensive debug logging to track progress samples and
identify calculation issues in the future.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Issue: File list only used half the vertical space, wasting screen real estate.
Changed left panel from VBox to Border layout:
- Top: "Clips to Merge" label and Add/Clear buttons (fixed size)
- Center: File list scroll area (expands to fill remaining space)
The border layout gives the scroll area priority to expand vertically,
maximizing the visible file list area. This is especially important
when merging many clips.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
User reports progress jumps to 100% within 10 seconds but merge continues for 45s total.
Added comprehensive debug logging to track:
- Individual clip durations as they're summed
- Total expected duration for the merge
- Exact moment when progress hits 100% with actual vs expected times
- Only update progress when it changes by ≥0.1% (reduces callback spam)
This will help diagnose whether:
- Clip durations are being calculated incorrectly
- FFmpeg's out_time_ms doesn't match expected total duration
- Concat demuxer reports different output duration than sum of inputs
Logging appears in logs/videotools.log with CatFFMPEG category.
To view: tail -f logs/videotools.log | grep FFMPEG
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Issues fixed:
- Missing file extensions caused FFmpeg errors (user's job 234 failure)
- Limited codec options (only copy or H.265)
- Manual codec mode selector was redundant
Changes:
1. Auto file extension handling:
- Automatically adds/corrects extension based on selected format
- .mkv for MKV/Blu-ray formats
- .mpg for DVD formats
- .mp4 for MP4 formats
- Validates and fixes extension in addMergeToQueue
2. Expanded format options:
- MKV (Copy streams) - stream copy, no re-encoding
- MKV (H.264) - re-encode with H.264, CRF 23
- MKV (H.265) - re-encode with H.265, CRF 28
- MP4 (H.264) - H.264 + AAC audio, web-optimized
- MP4 (H.265) - H.265 + AAC audio, web-optimized
- DVD NTSC/PAL (16:9 and 4:3)
- Blu-ray (H.264)
3. Removed redundant codec mode selector:
- Format dropdown now explicitly includes codec choice
- Cleaner, more intuitive UI
- Backward compatible with old queue jobs
Extension is auto-updated when:
- User selects a different format (updates existing path extension)
- User adds merge to queue (validates/fixes before encoding)
- Prevents errors from missing or wrong file extensions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Long FFmpeg error messages were pushing the queue UI off screen, making
the interface unusable when jobs failed with verbose errors.
Changes:
- Truncate error messages to 150 characters maximum in status text
- Add helpful message indicating full error is available via Copy Error button
- Enable text wrapping on status labels to handle multi-line content gracefully
- Prevents UI layout breakage while maintaining error visibility
Users can still access the full error message via:
- Copy Error button (copies full error to clipboard)
- View Log button (opens per-job conversion log)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The -progress flag was being added AFTER the output path in the FFmpeg command,
causing FFmpeg to not recognize it and therefore not output progress information.
Moved -progress pipe:1 -nostats to appear BEFORE the output path.
Now merge jobs will correctly report progress as they encode:
- Progress starts at 0%
- Updates based on out_time_ms from FFmpeg progress output
- Calculates percentage based on total duration of all clips
- Shows accurate real-time progress in queue view and stats bar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The Merge module's ui.NewDroppable wrappers weren't receiving drop events
because the window-level handleDrop function was intercepting them first.
Added merge module handling to handleDrop function:
- Accepts individual video files and adds them sequentially to merge clips
- Accepts multiple files at once and processes all in order
- Accepts folders and recursively finds all video files
- Probes each video to get duration and metadata
- Sets chapter names defaulting to filename
- Auto-sets output path to "merged.mkv" once 2+ clips are added
- Refreshes UI after each clip is added
Now drag-and-drop works consistently across all modules (Convert, Compare, Inspect, Merge).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>