Commit Graph

264 Commits

Author SHA1 Message Date
dd9e4a8afa Auto-set DVD bitrate and lock bitrate controls 2025-12-10 12:05:53 -05:00
68c1049c2f Tighten DVD preset messaging 2025-12-10 12:02:14 -05:00
db71ed5bfc Lock DVD presets to compliant defaults 2025-12-10 11:58:27 -05:00
ece59f04f3 Add merge chrome and guard NVENC runtime availability 2025-12-10 11:44:29 -05:00
c3d9282f5a Add 360p/480p/540p resolution presets 2025-12-09 16:14:15 -05:00
3e7583704b Add initial Merge module with chapters and queue support 2025-12-09 16:10:23 -05:00
b97182baac Clean up Logs menu and show log path 2025-12-09 14:34:39 -05:00
2682766eb5 Add 5:3 aspect option 2025-12-09 14:27:38 -05:00
d14225f402 Persist convert config and tidy queue UI 2025-12-09 13:24:39 -05:00
c6e352e436 Fix hardware fallback retry to keep build green 2025-12-09 13:13:03 -05:00
cfe21e786d Handle HW fallback retry return 2025-12-09 12:09:12 -05:00
b1b5412cdb Refine HW fallback: retry convert once in software 2025-12-09 11:50:48 -05:00
04e6f89323 Retry hardware failures inline with software and avoid UI crash 2025-12-09 11:08:37 -05:00
9f7583c423 Auto-retry convert in software if hardware encoder fails 2025-12-09 02:08:09 -05:00
af82ce2809 Force Source aspect unless user changes it; keep configs aligned 2025-12-09 02:06:06 -05:00
3a60494fca Include FFmpeg stderr in snippet job errors 2025-12-09 01:50:10 -05:00
038c1567eb Queue snippets and honor user aspect; skip HW accel if unavailable 2025-12-09 01:33:05 -05:00
510f739b85 Force Source aspect default on snippets to prevent 16:9 drift 2025-12-09 01:28:33 -05:00
8ffc8663a4 Do not change aspect on snippets unless user explicitly sets it 2025-12-09 01:16:53 -05:00
a056765673 Apply current convert settings to snippets (scale/aspect/fps/bitrate/preset) 2025-12-09 01:13:21 -05:00
4ad62b5d57 Fix config reload and inspect status ticker build errors 2025-12-09 00:40:52 -05:00
3c5785c720 Add config load/save, queue/status in inspect, keep aspect default 2025-12-09 00:16:56 -05:00
bd58a3c817 Fallback to software when auto hardware accel fails 2025-12-09 00:06:51 -05:00
20a2fa7110 Show bitrate in kbps/Mbps and expand presets 2025-12-08 23:53:40 -05:00
cdce97fca7 Default hardware accel to auto with helper selection 2025-12-08 23:28:47 -05:00
d094010440 Add simple bitrate/resolution/aspect controls and cache helper 2025-12-08 23:22:28 -05:00
2f16d4af36 Fallback bitrate uses source bitrate; add size/bitrate delta helpers 2025-12-08 22:26:06 -05:00
2d2d48fa68 Remove unused origBytes to fix Windows build 2025-12-08 20:51:29 -05:00
597160fadd Remove unused origBytes placeholder in compare metadata 2025-12-08 20:48:05 -05:00
3bc0d7da35 Suppress unused variable warning in compare metadata 2025-12-08 20:45:28 -05:00
f73a7c12c8 Add default bitrate fallback for CBR and format family labeling 2025-12-08 20:36:37 -05:00
bd49952800 Normalize MP4 format label, improve log readability, and prep reduction display 2025-12-08 18:46:34 -05:00
6ad72ecc46 Shorten queue descriptions and wrap text to keep controls visible 2025-12-08 18:13:18 -05:00
4f6746594a Fix feedback bundler export and use utils.NewFeedbackBundler 2025-12-08 16:06:58 -05:00
2dd9c7d279 Show app version and diagnostics in build scripts 2025-12-08 16:00:02 -05:00
550b66ccb9 Fix forward declarations for encoding/quality control helpers 2025-12-08 13:35:49 -05:00
c7a18e89c8 Group main menu by category and add logs access 2025-12-08 12:07:58 -05:00
f53da0c07f Add log viewer buttons and live log refresh for conversions 2025-12-08 12:02:25 -05:00
a8d66ad384 Move conversion logs to logs/ directory and surface logs in queue UI 2025-12-08 11:33:58 -05:00
8e601bc7d2 Add per-conversion logs and surface them in queue UI 2025-12-08 11:31:12 -05:00
f900f6804d Hide ffmpeg console windows on Windows and fix inspect clear button 2025-12-08 11:26:14 -05:00
fb9b01de0b Add horizontal/vertical flip and rotation transformations to Convert module
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>
2025-12-06 01:18:38 -05:00
7341cf70ce Add dev14 fixes: progress tracking, AMD AMF support, DVD resolution fix, and Windows build automation
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>
2025-12-04 17:11:15 -05:00
5b8fc452af Add FPS counter, queue improvements, Compare fixes, and comprehensive documentation
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>
2025-12-04 07:35:48 -05:00
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
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
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
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
Stu
103d8ded83 Add comprehensive encoder settings and fix window layout (v0.1.0-dev10)
Advanced Mode Encoder Settings:
- Added full video encoding controls: codec (H.264/H.265/VP9/AV1), encoder preset,
  manual CRF, bitrate modes (CRF/CBR/VBR), target resolution, frame rate,
  pixel format, hardware acceleration (nvenc/vaapi/qsv/videotoolbox), two-pass
- Added audio encoding controls: codec (AAC/Opus/MP3/FLAC), bitrate, channels
- Created organized UI sections in Advanced tab with 13 new control widgets
- Simple mode remains minimal with just Format, Output Name, and Quality preset

Snippet Generation Improvements:
- Optimized snippet generation to use stream copy for fast 2-second processing
- Added WMV detection to force re-encoding (WMV codecs can't stream-copy to MP4)
- Fixed FFmpeg argument order: moved `-t 20` after codec/mapping options
- Added progress dialog for snippets requiring re-encoding (WMV files)
- Snippets now skip deinterlacing for speed (full conversions still apply filters)

Window Layout Fixes:
- Fixed window jumping to second screen when loading videos
- Increased window size from 920x540 to 1120x640 to accommodate content
- Removed hardcoded background minimum size that conflicted with window size
- Wrapped main content in scroll container to prevent content from forcing resize
- Changed left column from VBox to VSplit (65/35 split) for proper vertical expansion
- Reduced panel minimum sizes from 520px to 400px to reduce layout pressure
- UI now fills workspace properly whether video is loaded or not
- Window allows manual resizing while preventing auto-resize from content changes

Technical Changes:
- Extended convertConfig struct with 14 new encoding fields
- Added determineVideoCodec() and determineAudioCodec() helper functions
- Updated buildConversionCommand() to use new encoder settings
- Updated generateSnippet() with WMV handling and optimized stream copy logic
- Modified buildConvertView() to use VSplit for flexible vertical layout

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 20:17:17 -05:00
Stu
183602a302 Add drag-and-drop, fix cover art encoding, extract embedded thumbnails (v0.1.0-dev9)
Drag-and-Drop on Main Menu:
- Implemented position-based drop detection on main menu module tiles
- Added detectModuleTileAtPosition() to calculate which tile receives the drop
- Modified window drop handler to pass position and route to appropriate module
- Bypasses Fyne's drop event hierarchy limitation where window-level handlers
  intercept drops before widgets can receive them
- Only enabled tiles (currently Convert) respond to drops
- Loads video and switches to module automatically

Cover Art Embedding Fixes:
- Fixed FFmpeg exit code 234 error when embedding cover art
- Added explicit PNG codec specification for cover art streams
- Snippet generation: Added `-c✌️1 png` after mapping cover art stream
- Full conversion: Added `-c✌️1 png` for proper MP4 thumbnail encoding
- MP4 containers require attached pictures to be PNG or MJPEG encoded

Embedded Cover Art Extraction:
- Added EmbeddedCoverArt field to videoSource struct
- Extended ffprobe parsing to detect attached_pic disposition
- Automatically extracts embedded thumbnails when loading videos
- Extracted cover art displays in metadata section (168x168)
- Enables round-trip workflow: generate snippet with thumbnail, load snippet
  and see the embedded thumbnail displayed

Technical Details:
- Modified handleDrop to accept position parameter
- Added Index and Disposition fields to ffprobe stream parsing
- Cover art streams now excluded from main video stream detection
- Grid layout: 3 columns, ~302px per column, ~122px per row, starts at y=100
- Embedded thumbnails extracted to /tmp/videotools-embedded-cover-*.png

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 18:46:51 -05:00
Stu
18a14c6020 Refactor to modular architecture with rainbow UI (v0.1.0-dev8)
Major refactoring to improve code organization and enhance UI:

Architecture:
- Split monolithic main.go into modular internal/ package structure
- Created internal/logging for centralized logging system
- Created internal/modules for module handler functions
- Created internal/ui for UI components and layouts
- Created internal/utils for shared utility functions

UI Enhancements:
- Implemented rainbow gradient across 8 module buttons (violet→red)
- Increased module button text size to 20 for better readability
- Fixed text centering on module tiles
- Converted Simple/Advanced mode toggle to tabs to save vertical space
- Added vertical scrollbars to prevent UI overflow
- Added metadata copy button (📋) to copy all metadata to clipboard

Video Processing:
- Fixed aspect ratio conversion to default to center-crop behavior
- Added 6 aspect handling modes: Auto, Crop, Letterbox, Pillarbox, Blur Fill, Stretch
- Fixed blur fill to maintain source resolution with padding (no scaling)
- Ensured all FFmpeg filters produce even-numbered dimensions for H.264

Known Issues:
- WMV files still produce FFmpeg error 234 during aspect conversions
  (requires codec-specific handling in future update)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 14:56:37 -05:00
Stu
35b04bfe98 Change default aspect ratio from 16:9 to Source
Updated the convert menu to default to source aspect ratio instead of 16:9,
which better preserves the original video's aspect ratio by default.

Changes:
- Initial state default: 16:9 → Source
- Empty fallback default: 16:9 → Source
- Reset button default: 16:9 → Source
- Clear video default: 16:9 → Source
- Updated hint label to reflect new default

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 02:36:40 -05:00
Stu
99be801c1d Add aspect controls, cancelable converts, and icon 2025-11-21 18:57:28 -05:00
Stu
b2fe80062e Default output name to -convert suffix 2025-11-21 16:23:36 -05:00
Stu
8420afb000 Wire convert button with status indicator 2025-11-21 16:22:50 -05:00
Stu
f7a7246301 Add clear video control in metadata panel 2025-11-21 16:15:31 -05:00
Stu
b7361f6528 Improve seek handling for embedded playback 2025-11-21 16:07:21 -05:00
Stu
2a677a7fe0 Fix embedded video rendering and stabilize seek 2025-11-21 16:01:20 -05:00
Stu
b26c4183fd Implement in-app playback with ffmpeg frame pump and Go audio 2025-11-20 16:11:56 -05:00
Stu
e054a39c97 Add mute toggle and volume state tracking 2025-11-20 15:35:11 -05:00
Stu
35612dcc91 Swap player icons to monochrome set and track pause state 2025-11-20 15:34:59 -05:00
Stu
fb05328de7 Improve video player layout with overlay controls 2025-11-20 15:06:52 -05:00
Stu
ec7fd07ee8 feat: initial GUI prototype 2025-11-19 15:10:18 -05:00