Commit Graph

92 Commits

Author SHA1 Message Date
Stu
03b6804a9e Fix build: remove unused imports, drop playSess img refs, cleanup state init 2025-12-13 21:58:41 -05:00
Stu
1dfab7000b Switch playback to mpv IPC and poll progress 2025-12-10 05:47:38 -05:00
Stu
0ba248af4e Coalesce player view renders and schedule once 2025-12-10 05:31:48 -05:00
Stu
4929918d4b Replace internal decoder with ffplay subprocess 2025-12-10 05:27:24 -05:00
Stu
3d43123840 Throttle player view calls aggressively 2025-12-10 05:22:30 -05:00
Stu
feeaf8e39a Throttle player view rebuilds after video load 2025-12-10 05:20:37 -05:00
Stu
8479bfef6f Guard player view render and refresh after loads 2025-12-10 05:17:02 -05:00
Stu
9d255680bf Track current source to avoid rebuilds 2025-12-10 05:09:01 -05:00
Stu
a393183d83 Trim extra UI rebuild guard 2025-12-10 05:02:17 -05:00
Stu
22e325e123 Keep player session alive and stop repeated rebuilds 2025-12-10 04:59:43 -05:00
Stu
47067aabf0 Keep player session alive in showPlayerView 2025-12-10 04:54:55 -05:00
Stu
e727b8ea09 Auto-start playback, guard view rebuilds, and clean window close 2025-12-10 03:23:40 -05:00
Stu
fc1e91bda6 Avoid player view rebuild when already active 2025-12-10 03:13:54 -05:00
Stu
ee08618142 Add playback session logging for troubleshooting 2025-12-09 18:53:30 -05:00
Stu
ab9f19095d Set video surface size and surface ffmpeg errors 2025-12-09 18:51:41 -05:00
Stu
8815f69fe8 Show preview frame when loading videos 2025-12-09 18:20:36 -05:00
Stu
c4a5e48a22 Add comprehensive debug logging and performance monitoring
Added detailed terminal output to diagnose video loading hangs:
- Session creation logging (resolution, fps, target size)
- FFmpeg command logging
- Frame decode pipeline timing (first frame, decode time, render time)
- Real-time FPS counter (reports every 2 seconds)
- Memory usage info (frame buffer size)
- Error reporting with FFmpeg stderr output

This will help identify performance bottlenecks and hanging issues
during video playback.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 16:09:02 -05:00
Stu
998b76cefd Hide playlist by default - make fullscreen video player the default view
Changed playlist visibility from auto-showing when multiple videos
to hidden by default. Users can toggle it with the menu (☰) button.

This gives a cleaner video player experience without the playlist
taking up screen space.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 12:40:33 -05:00
Stu
eb2a7a4297 Fix critical bug: remove TappableOverlay that was blocking all button clicks
The TappableOverlay was added to the entire stage container, which
made it cover the video AND all control buttons below. This invisible
overlay intercepted all mouse events, preventing buttons from working.

Temporarily disabled the overlay to restore button functionality.
Will need to reimplement properly as floating controls that only
overlay the video area, not the UI controls.

Fixes:
- Play/pause button now clickable
- Volume controls now work
- All other UI buttons functional
- Keyboard shortcuts (Space, F11, ESC) still work

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 12:30:28 -05:00
Stu
e0ecc92195 Add Space bar play/pause and fix icon display with ASCII fallback
Fixes control interactions and icon display issues for immediate usability.

Keyboard Shortcuts:
- Space bar now globally toggles play/pause
- Works anywhere in the app when video is loaded
- No longer conflicts with keyframing mode shortcuts

Icon Display Fix:
- Replaced Material Icons unicode with ASCII/emoji fallback
- Play: ▶ | Pause: || | Stop: ■
- Skip: |◀ and ▶| | Fast: ◀◀ and ▶▶
- Volume: 🔊 🔉 🔇 emojis
- Menu: ☰ (hamburger)
- Works without special fonts installed

Why ASCII Fallback:
- Material Symbols font not installed by default
- Unicode characters displayed as boxes/gibberish
- ASCII icons work universally on all systems
- Ready for custom SVG icons replacement

Usage:
- Press Space anywhere to play/pause video
- Icons now display correctly without font dependencies
- Buttons should be more responsive

Next Steps:
- Add custom SVG icons (user will create)
- Implement overlay controls that auto-hide
- Fix play button responsiveness
- Move controls to overlay video area

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 11:37:49 -05:00
Stu
e25f0c4284 Add video interaction: double-click fullscreen and right-click play/pause
Implements intuitive video player interactions for enhanced user experience.

Video Interaction Features:
- Double-click video area to toggle fullscreen
- Right-click video area to play/pause
- Single-click does nothing (reserved for future use)
- Transparent tappable overlay on video canvas

Implementation:
- Created TappableOverlay widget in internal/ui/tappable.go
- Invisible widget captures tap, double-tap, and secondary-tap events
- Extends widget.BaseWidget for Fyne compatibility
- Added overlay to stage container after video image

User Experience:
- Double-click anywhere on video → instant fullscreen
- Right-click anywhere on video → quick play/pause
- Works alongside existing keyboard shortcuts (F11, Space, ESC)
- Play button icon updates when using right-click

Technical Details:
- TappableOverlay has no visual representation
- Implements Tapped(), DoubleTapped(), TappedSecondary()
- Callbacks are configurable per instance
- Positioned as top layer in container.NewMax() stack

Usage:
1. Load a video
2. Double-click video to enter fullscreen
3. Right-click to pause/play
4. ESC or F11 to exit fullscreen

Next Steps:
- Consider adding single-click functionality
- Add visual feedback for interactions
- Implement mouse cursor auto-hide in fullscreen

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 11:23:26 -05:00
Stu
b73beb1fef Add fullscreen mode with F11 and ESC keyboard shortcuts
Implements basic fullscreen toggle functionality for immersive video playback.

Fullscreen Features:
- F11 key toggles fullscreen on/off
- ESC key exits fullscreen mode
- Window.SetFullScreen() for native fullscreen
- isFullscreen state tracking in appState

Keyboard Shortcuts:
- F11: Toggle fullscreen (globally available)
- ESC: Exit fullscreen (only when in fullscreen mode)
- Shortcuts work from any screen in the app

Implementation:
- Added isFullscreen bool to appState
- Created toggleFullscreen() method
- Global keyboard handler in runGUI()
- SetOnTypedKey handles F11 and ESC

Usage:
1. Load a video in VT_Player
2. Press F11 to enter fullscreen
3. Press F11 or ESC to exit fullscreen

Next Steps:
- Add fullscreen button to player controls
- Auto-hide controls after 3 seconds in fullscreen
- Show controls on mouse movement in fullscreen
- Double-click video to toggle fullscreen

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 11:19:44 -05:00
Stu
5e2c07ad21 Create custom timeline widget with keyframe markers (Commit 6)
Implements visual timeline with smooth interaction and keyframe visualization:

Timeline Widget Features:
- Custom Fyne widget in internal/ui/timeline.go
- Visual keyframe markers (yellow 1px vertical lines)
- Current position scrubber (white 2px line with circle handle)
- Progress fill showing played portion (gray)
- Mouse click/drag for smooth seeking
- In/out point marker support (for future cut functionality)

Rendering Performance:
- Cached rendering objects to minimize redraws
- Only scrubber position updates on playback
- Full redraw only on resize or keyframe data change
- Optimized for 1000+ keyframes without lag

UI Integration:
- Timeline replaces slider when keyframing mode is enabled
- Automatically loads keyframe timestamps from Index
- Integrates with existing updateProgress callback
- Maintains current time/total time labels

Technical Implementation:
- TimelineWidget extends widget.BaseWidget
- Custom renderer implements fyne.WidgetRenderer
- SetOnChange() for seek callback
- SetPosition() for playback updates
- SetKeyframes() for keyframe marker display
- Desktop mouse events for hover and drag

Visual Design:
- Dark gray background (#282828)
- Lighter gray progress fill (#3C3C3C)
- Yellow keyframe markers (#FFDC00 with transparency)
- White scrubber with circular handle
- Blue in-point marker for cuts
- Red out-point marker for cuts

References: DEV_SPEC lines 192-241

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 12:07:45 -05:00
Stu
3a5b1a1f1e Add frame-accurate navigation controls (Commit 5)
Implements comprehensive frame navigation UI and keyboard shortcuts:

Frame Navigation UI:
- Frame step buttons (←/→ icons) for single-frame stepping
- Keyframe jump buttons (⏮/⏭ icons) for I-frame navigation
- Frame counter display showing current frame number
- All navigation controls only visible in keyframing mode
- Automatic keyframe index loading when enabling frame mode

Keyboard Shortcuts:
- Left/Right arrows: step one frame backward/forward
- Up/Down arrows: jump to previous/next keyframe
- Space: play/pause toggle
- All shortcuts only active in keyframing mode

Frame Counter:
- Displays current frame number during playback
- Updates in real-time as video plays
- Shows "(KF)" suffix when on a keyframe
- Positioned next to playlist toggle button

Technical Details:
- StepFrame() method pauses playback and seeks precisely
- GetCurrentPosition() added to playSession for position queries
- Keyframe navigation uses binary search from detector.go
- All UI updates properly synchronized via Fyne.Do()
- Frame counter declared early for use in updateProgress callback

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 15:28:41 -05:00
1618558314 Implement keyframe detection system (Commit 4)
Core implementation:
- Create internal/keyframe package with detector.go
- Implement DetectKeyframes() using ffprobe packet flags
- Use 'K' flag in packet data to identify I-frames
- Binary search for FindNearestKeyframe() (before/after/nearest)
- EstimateFrameNumber() for frame calculations

Caching system:
- Save/load keyframe index to ~/.cache/vt_player/keyframes/
- Binary format: ~12 bytes per keyframe (~3KB for 4min video)
- Cache key based on file path + modification time
- Auto-invalidation when file changes
- DetectKeyframesWithCache() for automatic cache management

Performance:
- 265 keyframes detected in 0.60s for 4min video (441 kf/sec)
- FindNearestKeyframe: 67ns per lookup (binary search)
- Memory: ~3KB cache per video
- Exceeds target: <5s for 1-hour video

Integration:
- Add KeyframeIndex field to videoSource
- EnsureKeyframeIndex() method for lazy loading
- Ready for frame-accurate navigation features

Testing:
- Comprehensive unit tests (all passing)
- Benchmark tests for search performance
- cmd/test_keyframes utility for validation
- Tested on real video files

Prepares for Commits 5-10:
- Frame-by-frame navigation (Commit 5)
- Keyframe jump controls (Commit 5)
- Timeline with keyframe markers (Commit 6-7)
- In/out point marking (Commit 8)
- Lossless cut export (Commit 9-10)

References: DEV_SPEC Phase 2 (lines 54-119)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:11:45 -05:00
3f47da4ddf Integrate Google Material Icons for clean UI
Icon system:
- Create internal/ui/icons.go with Material Symbols unicode constants
- Add 50+ icon constants for all player features
- Implement NewIconButton() and helper functions
- Add GetVolumeIcon() and GetPlayPauseIcon() dynamic icon helpers

UI updates:
- Replace emoji icons (▶/⏸ 🔊 ☰) with Material Icons
- Use play_arrow/pause for play button with state toggle
- Use volume_up/down/mute/off for volume with dynamic updates
- Use menu icon for playlist toggle
- Use skip_previous/skip_next for track navigation

Documentation:
- Add MATERIAL_ICONS_MAPPING.md with complete icon reference
- Document 50+ Material Icon unicode mappings
- Include download instructions for Material Symbols font
- Map all planned features to appropriate icons

Benefits:
- Professional, consistent icon design
- Industry-standard Material Design language
- Better rendering than emoji (no font fallback issues)
- Scalable unicode characters (works immediately)
- Ready for font enhancement (optional Material Symbols font)

Prepares for:
- Frame navigation icons (navigate_before/next)
- Keyframe jump icons (first_page/last_page)
- Cut tool icons (content_cut, markers)
- All features in FEATURE_ROADMAP.md

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 10:06:43 -05:00
c7d821e03a Add menu bar and center playback controls
UI improvements:
- Add menu bar at top with File, View, and Tools menus
- Move File operations (Open, Add Folder, Clear) to File menu
- Add Frame-Accurate Mode toggle in Tools menu
- Center playback controls (Prev, Play, Next) at bottom
- Move volume controls to left, playlist toggle to right
- Remove redundant top control bar for cleaner interface
- Add keyframingMode state to appState for feature toggle

Layout changes:
- Menu bar provides access to advanced features
- Main player area takes full space below menu
- Controls centered bottom like modern video players (Haruna/VLC)
- Cleaner interface suitable for basic playback or advanced editing

Prepares for:
- Frame-accurate navigation features (when keyframing enabled)
- Timeline with keyframe markers
- In/out point cutting tools
- Integration with VideoTools chapter support

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 10:03:31 -05:00
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