Commit Graph

65 Commits

Author SHA1 Message Date
5e2171a95e Fix video loading and improve player UI
Major fixes:
- Fix drag-and-drop video loading bug (s.source was never set)
- Call switchToVideo() instead of showPlayerView() to properly initialize player state
- Show initial preview frame/thumbnail when video loads
- Improve ffprobe error messages (capture stderr for better diagnostics)

UI improvements:
- Move playlist from left to right side
- Add playlist toggle button (☰) with visibility control
- Load and display preview frame immediately when video loads
- Improve control layout with volume container
- Auto-hide playlist when only one video loaded

Documentation:
- Add FEATURE_ROADMAP.md tracking 30 planned features
- Add ICONS_NEEDED.md listing 53 required SVG icons
- Update .gitignore to exclude binaries

References: DEV_SPEC_FRAME_ACCURATE_PLAYBACK.md

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 10:01:59 -05:00
Stu
e1b1f0bb94 Fix build: import net/url 2025-12-04 07:16:50 -05:00
Stu
3f43b3fe4b Rename app/window to VT Player 2025-12-04 07:10:18 -05:00
Stu
b7b5788938 Harden drag/drop path handling and user feedback 2025-12-04 07:08:12 -05:00
Stu
ffca39811a Improve drag/drop path handling and landing layout 2025-12-04 06:59:08 -05:00
Stu
e749a32926 Remove legacy compare/convert hooks 2025-12-04 06:40:00 -05:00
Stu
66c79cee91 Remove duplicate compare/queue handlers 2025-12-04 06:28:06 -05:00
Stu
7fe4f78b94 Add compare view and drop-to-play only handler 2025-12-04 06:12:02 -05:00
Stu
d5458f7050 Simplify player view and enable drop-to-play 2025-12-04 06:04:35 -05:00
Stu
eaea93e0e6 Initial import for VT Player 2025-12-04 05:03:02 -05:00
71a282b828 Add Compare module and Target File Size encoding feature
This commit implements two new features:

1. Compare Module:
   - New UI module for side-by-side video comparison
   - Loads two video files and displays detailed metadata comparison
   - Shows format, resolution, codecs, bitrates, frame rate, color info, etc.
   - Accessible via GUI module button or CLI: videotools compare <file1> <file2>
   - Added formatBitrate() helper function for consistent bitrate display

2. Target File Size Encoding Mode:
   - New bitrate mode "Target Size" for convert module
   - Allows users to 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

Additional changes:
- Updated printUsage() to include compare command
- Added compare button to module grid with pink color
- Added compareFile1 and compareFile2 to appState
- Consistent "Target Size" naming throughout (UI and code)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:14:31 -05:00
6a2f1fff3f Add target file size feature and fix multiple encoding issues
- Add TargetFileSize mode with automatic bitrate calculation
- Add CalculateBitrateForTargetSize and ParseFileSize utility functions
- Fix NVENC hardware encoding (remove incorrect -hwaccel cuda flag)
- Fix auto-detection override when hardware accel set to none
- Fix 10-bit pixel format incompatibility (change to 8-bit yuv420p)
- Add enhanced video metadata display (PAR, color space, GOP size, audio bitrate, chapters)
- Improve error reporting with FFmpeg stderr capture and exit code interpretation
- Add interpretFFmpegError function for human-readable error messages
2025-12-03 10:00:14 -05:00
50163f6ea5 Release v0.1.0-dev12: Advanced encoding and compatibility
Major Features:
- Automatic hardware encoder detection (NVENC/QSV/VA-API)
- iPhone compatibility with H.264 profile/level support
- Dual deinterlacing methods (bwdif + yadif)
- 10-bit encoding for 10-20% size reduction
- Browser desync fix with genpts and CFR enforcement
- Audio normalization (stereo + 48kHz)
- Extended resolution support (8K)
- Black bar cropping infrastructure

Technical Improvements:
- Automatic best encoder selection
- VFR to CFR conversion prevents playback issues
- Backward compatible with legacy settings
- Comprehensive encoding decision logging

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 18:12:50 -05:00
81daccde60 Track current convert filenames to label UI correctly 2025-11-30 01:13:06 -05:00
cd3a9dcb68 Return from queue to last module when opened in-context 2025-11-30 01:09:52 -05:00
26c4af25af Count active direct convert in main menu queue label 2025-11-30 01:07:20 -05:00
14de3d494d Refresh queue view during direct conversion progress 2025-11-30 01:06:00 -05:00
c5124e4b29 Skip cover art for DVD targets to avoid mux errors 2025-11-30 01:02:48 -05:00
cf700b2050 Include direct convert in queue totals 2025-11-30 01:00:05 -05:00
58773c509c Track direct conversion progress in stats and queue 2025-11-30 00:58:46 -05:00
d71a50eff1 Clarify direct conversion in stats and queue list 2025-11-30 00:52:26 -05:00
846cd64419 Defer queue start until direct convert finishes 2025-11-30 00:50:54 -05:00
e0e7c33445 Preserve queue scroll and show active conversion inline 2025-11-30 00:48:56 -05:00
0116b53479 Show active direct conversion in stats and queue view 2025-11-30 00:40:33 -05:00
e094872fce Allow queueing while a conversion is in progress 2025-11-30 00:37:14 -05:00
a345b5a457 Fix DVD target option ordering for direct and queued converts 2025-11-30 00:34:32 -05:00
c85fd8503e Align queued DVD jobs with direct convert settings 2025-11-30 00:29:05 -05:00
c237cb8a8e Fix queue scroll jump and DVD format codec selection 2025-11-30 00:15:04 -05:00
54eab7d800 Enforce DVD codecs and targets for mpg outputs 2025-11-30 00:05:40 -05:00
1187a77f43 Fix convert layout stacking and cgo build 2025-11-30 00:01:06 -05:00
704ed38fcd Prevent simultaneous conversions - enforce queue-only mode when queue is running
Implements mutual exclusion between 'Convert Now' and queue processing:

Behavior:
- If queue is running: 'Convert Now' button is DISABLED
- If user tries to click 'Convert Now' while queue runs: Shows info dialog
  with message and auto-adds video to queue instead
- Only one conversion method active at a time

This prevents:
- Multiple simultaneous FFmpeg processes competing for system resources
- Confusion about which conversion is running
- Queue and direct conversion interfering with each other

When queue is active:
- 'Convert Now' button: DISABLED (grey out)
- 'Add to Queue' button: ENABLED (highlighted)
- Clear UI signal: Only use queue mode for batch operations

Perfect for batch workflows where user loads multiple videos
and expects them all to process sequentially in the queue,
not spawn random direct conversions.
2025-11-29 20:36:13 -05:00
b3db00c533 Auto-start queue when adding jobs from Convert module
Implements automatic queue processing when jobs are added from the Convert
module via the 'Add to Queue' button:

Features:
- IsRunning() method added to queue package to check processing status
- 'Add to Queue' button now auto-starts queue if not already running
- Eliminates need to manually open Queue view and click 'Start Queue'
- Seamless workflow: Add video → Queue → Auto-starts conversion

Before:
1. Load video
2. Click 'Add to Queue'
3. Click 'View Queue'
4. Click 'Start Queue'

After:
1. Load video
2. Click 'Add to Queue' (auto-starts!)
3. Load next video
4. Click 'Add to Queue' (already running)

Perfect for batch operations where user loads multiple videos and expects
them to start encoding immediately.
2025-11-29 20:31:52 -05:00
f306cf32e6 Add batch settings management UI for multi-video conversions
Implements clear batch settings control for converting multiple videos:

Features:
- Settings persistence: All conversion settings automatically persist across videos
- Clear UI messaging: Explains that settings carry over between videos
- Reset button: One-click ability to reset all settings to defaults
- Batch workflow: Load video → set format/quality once → convert multiple videos

How it works:
1. User loads first video and configures settings (format, quality, codecs, etc)
2. Settings are stored in state.convert and persist across video loads
3. User can load additional videos - settings remain the same
4. When converting multiple videos, all use the same settings
5. User can change settings anytime - affects all subsequent videos
6. Reset button available to restore defaults if needed

This eliminates the need to reconfigure every video while allowing:
- Batch processing with same settings
- Individual video settings override when needed
- Clear visual indication of what's happening

Perfect for the user's workflow of converting 5 European videos to
DVD-NTSC format - set once, convert all 5!
2025-11-29 20:30:39 -05:00
eab41057aa Implement DVD format FFmpeg codec selection and settings
Critical fix: When a DVD format (NTSC or PAL) is selected, now properly
override the video and audio codec to use DVD-compliant standards:

Video:
- Forces MPEG-2 codec (mpeg2video)
- NTSC: 6000k bitrate, 9000k max, gop=15
- PAL: 8000k bitrate, 9500k max, gop=12

Audio:
- Forces AC-3 codec for DVD container compatibility
- 192 kbps bitrate
- 48 kHz sample rate (DVD standard)
- Stereo channels (2)

This ensures that selecting a DVD format produces DVDStyler-compatible
MPEG files without codec errors. Previously, the code was using the
default H.264 + AAC, which caused 'unsupported audio codec' errors
when trying to write to MPEG container.

Fixes the issue where DVD conversions were failing with:
  'Unsupported audio codec. Must be one of mp1, mp2, mp3, 16-bit pcm_dvd,
   pcm_s16be, ac3 or dts.'
2025-11-29 20:28:12 -05:00
684dc961e8 Fix Fyne threading error by using async Do() instead of DoAndWait()
The setContent function was calling fyne.DoAndWait() from the main goroutine,
which created a deadlock. Changed to use fyne.Do() (asynchronous) to properly
marshal UI updates without blocking.

This resolves the error:
  'fyne.Do[AndWait] called from main goroutine'

The async approach is correct here since we don't need to wait for the
content update to complete before continuing.
2025-11-29 20:25:57 -05:00
d327d7f65e Improve queue system reliability and add auto-resolution for DVD formats
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)
2025-11-29 20:07:35 -05:00
ce60508480 Add build/run scripts and fix DVD options visibility
Added scripts folder with three convenience scripts:
  • scripts/build.sh - Clean build with dependency verification
  • scripts/run.sh - Run application (auto-builds if needed)
  • scripts/alias.sh - Create 'VideoTools' command alias

Usage:
  source scripts/alias.sh
  VideoTools              # Run app
  VideoToolsRebuild       # Force rebuild
  VideoToolsClean         # Clean artifacts

Fixed main.go DVD options:
  • Fixed callback ordering so updateDVDOptions is called on format selection
  • DVD aspect ratio selector now appears when DVD format is selected
  • DVD info display shows specs for NTSC and PAL formats
  • Works in both Simple and Advanced tabs

DVD options are now fully functional in the UI.
2025-11-29 19:53:47 -05:00
ae8177ffb0 Add DVD format options to Convert module UI
Integrated DVD-NTSC and DVD-PAL options into the Convert module's Simple and Advanced modes.

New Features:
✓ DVD-NTSC (720×480 @ 29.97fps) option in format selector
✓ DVD-PAL (720×576 @ 25.00fps) option in format selector
✓ DVD aspect ratio selector (4:3 or 16:9)
✓ Dynamic DVD options panel - appears only when DVD format selected
✓ Informative DVD specs displayed based on format selection
✓ Smart show/hide logic for DVD-specific controls
✓ Works in both Simple and Advanced mode tabs

DVD Specifications Displayed:
- NTSC: 720×480 @ 29.97fps, MPEG-2, AC-3 Stereo 48kHz
- PAL: 720×576 @ 25.00fps, MPEG-2, AC-3 Stereo 48kHz
- Bitrate ranges and compatibility info

Users can now:
1. Select DVD format from dropdown
2. Choose aspect ratio (4:3 or 16:9)
3. See relevant DVD specs and compatibility
4. Queue DVD conversion jobs
5. Process with existing queue system

🤖 Generated with Claude Code
2025-11-29 19:39:20 -05:00
fa4f4119b5 Simplify threading solution and add Clear All button
Simplified the approach by removing complex callback logic and using a
simple 500ms timer-based update for the stats bar instead. This eliminates
threading errors completely while keeping the code straightforward.

Changes:
1. Removed queue change callback entirely
2. Added background timer that updates stats bar every 500ms
3. Removed initComplete flag (no longer needed)
4. Simplified setContent() to direct calls
5. Added onClearAll parameter to BuildQueueView()
6. Added ClearAll() method to Queue (removes all jobs)
7. Added Clear All button with DangerImportance styling in queue view
8. Clear Completed button now has LowImportance styling

This approach is much simpler: the UI just polls the queue state
periodically instead of trying to handle callbacks from goroutines.
No more threading errors, less code, easier to understand.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:25:03 -05:00
b80b81198f Fix threading errors with proper initialization guard
The threading errors were caused by queue callbacks triggering showMainMenu()
during app initialization, before the Fyne event loop was fully ready.

Changes:
1. Added initComplete flag to appState struct
2. Queue callback returns early if !initComplete, preventing UI updates
   during initialization
3. Set initComplete=true AFTER ShowAndRun() would handle the event loop
4. Removed nested DoFromGoroutine() which was causing double-wrapping
5. Simplified setContent() to direct calls (no thread wrapping)
6. Callback properly marshals UI updates via DoFromGoroutine() after init

This ensures the queue callback only affects UI after the app is fully
initialized and the Fyne event loop is running.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:23:03 -05:00
fb472bc677 Fix Fyne threading errors in queue callbacks and setContent
The queue callback was triggering showMainMenu() from a goroutine (the
job processor) without marshaling to the main thread. This caused the
threading error "should have been called in fyne.Do[AndWait]".

Changes:
1. Queue callback now wraps all UI updates in app.Driver().DoFromGoroutine()
   to safely marshal calls from the job processor goroutine to the main thread
2. setContent() now always uses DoFromGoroutine() to ensure thread safety
   regardless of caller context. This prevents errors when called from
   callbacks or other goroutines.
3. Added fallback for early initialization when app driver isn't ready yet

This ensures all UI updates happen on the main Fyne event loop thread.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:20:39 -05:00
27f80cb056 Add multi-video selection support for batch queue operations
Implemented three methods to add multiple videos to the queue:

1. **Drag from main menu**: When on the main menu, dragging multiple videos
   onto the Convert tile automatically adds them all to the queue via
   batchAddToQueue(). Already working - improved handling.

2. **Drag onto convert module**: When in the convert module, dragging
   multiple video files now adds all of them to the queue instead of just
   loading the first one. Single files are loaded as before.

3. **UI button support**: Added 'Add Multiple...' button next to 'Open File...'
   to make it clear that users can load multiple files.

Changes:
- handleDrop(): Refactored to process all dropped files when in convert module
  and call batchAddToQueue() for multiple videos
- buildVideoPane(): Added 'Add Multiple...' button and reorganized button
  layout to show both single and batch options

This provides intuitive multi-file handling with three different workflows
for users who prefer different input methods.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:18:24 -05:00
1c8d48e3fd Corrections made to queue system 2025-11-27 00:17:59 -05:00
0e4f4fb3af Fix queue persistence and threading issues - proper solution
- Remove queue loading at startup: Queue now starts completely fresh each
  session. No Load() call from /tmp/videotools-queue.json
- Remove queue saving at shutdown: Queue is not persisted between sessions
- Delay callback registration: SetChangeCallback() is now called via
  goroutine with 100ms delay to ensure UI is fully initialized before
  callbacks can trigger showMainMenu()
- Keep simple setContent(): Direct calls to SetContent(), no threading
  wrapper needed during normal operation

This ensures:
1. No threading errors on app startup
2. Clean empty queue on each new session
3. Proper initialization order preventing callback-during-init issues

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:13:29 -05:00
813c0fd17d Revert "Fix Fyne threading error and queue persistence issues"
This reverts commit cfb608e191.
2025-11-27 00:12:00 -05:00
cfb608e191 Fix Fyne threading error and queue persistence issues
This commit resolves three critical issues:

1. **Fyne Threading Error on Startup**: Fixed by improving setContent() to
   check the initComplete flag. During initialization, setContent() calls
   SetContent() directly since we're on the main thread. After initialization,
   it safely marshals calls via app.Driver().DoFromGoroutine().

2. **Queue Persisting Between Sessions**: Fixed by removing queue persistence.
   The shutdown() function no longer saves the queue to disk, ensuring a
   clean slate for each new app session.

3. **Queue Auto-Processing**: Fixed by making the queue start in 'paused'
   state. Users must explicitly click 'Process Queue' to start batch
   conversion. Queue methods PauseProcessing() and ResumeProcessing()
   control the paused state.

Changes:
- main.go: Added initComplete flag to appState, improved setContent()
  logic, disabled queue persistence in shutdown()
- queue/queue.go: Added paused field to Queue struct, initialize paused=true,
  added PauseProcessing()/ResumeProcessing() methods
- ui/queueview.go: Added UI controls for queue processing and clearing

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 00:06:19 -05:00
8a67ce74c8 Fix queue deserialization for formatOption struct
Handle case where formatOption is loaded from JSON as a map instead
of a struct. This prevents panic when reloading saved queue on startup.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 18:48:28 -05:00
43ed677838 Add persistent conversion stats, multi-video navigation, and error debugging
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>
2025-11-26 18:44:54 -05:00
b09ab8d8b4 Add job queue system with batch processing support
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>
2025-11-26 17:19:40 -05:00
d7ec373470 Fix conversion progress updates when navigating between modules
Previously, when a conversion was started and the user navigated away from
the Convert module and returned, the progress stats would freeze (though the
progress bar would continue animating). This was caused by the conversion
goroutine updating stale widget references.

Changes:
- Decoupled conversion state from UI widgets
- Conversion goroutine now only updates appState (convertBusy, convertStatus)
- Added 200ms UI refresh ticker in buildConvertView to update widgets from state
- Removed all direct widget manipulation from background conversion process

This ensures conversion progress stats remain accurate and update correctly
regardless of module navigation, supporting the persistent video context
design where conversions continue running while users work in other modules.
2025-11-25 18:49:01 -05:00