Compare commits

...

6 Commits

Author SHA1 Message Date
58c55d3bc6 Remove refactoring and HandBrake replacement documentation files 2025-12-30 16:09:33 -05:00
03e036be51 Update output filename preview in real-time when toggling suffix
- Output hint now updates immediately when checking/unchecking suffix checkbox
- User can see "video.mp4" vs "video-convert.mp4" change live
- Improves UX by providing instant visual feedback

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 16:06:10 -05:00
ebf71a3214 Remove HandBrake replacement documentation references
- Removed reference to HANDBRAKE_REPLACEMENT.md from docs/README.md
- Removed HandBrake references from docs/CHANGELOG.md
- Keep documentation focused on VideoTools features
- File was already deleted, this cleans up the references

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 15:55:38 -05:00
e1c4d9ca50 Fix DVD authoring VOBU errors with proper MPEG-PS muxing
Critical fix for dvdauthor "Skipping sector at inoffset 0" errors:

- Add -f dvd format to initial MPEG encoding
- Add -muxrate 10080000 (10.08 Mbps DVD standard mux rate)
- Add -packetsize 2048 (DVD packet size requirement)
- Apply same parameters to remux and concat steps
- Ensures proper VOBU (Video Object Unit) boundaries
- Creates DVD-compliant MPEG-PS streams from encoding

This fixes the "dvdauthor structure creation failed" error when
authoring multi-scene DVDs. The MPEG files now have proper DVD
navigation structure that dvdauthor can process.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 15:41:03 -05:00
19739b0fab Make "-convert" suffix optional with checkbox (off by default)
- Added AppendSuffix bool field to convertConfig (default: false)
- By default, output filename matches source filename exactly
- Added checkbox "Append \"-convert\" to filename" (unchecked by default)
- Checkbox appears in both Simple and Advanced modes
- Eliminates noise when doing batch conversions
- Auto-naming still works and respects the suffix setting

Before: video.mp4 → video-convert.mp4 (always)
After: video.mp4 → video.mp4 (or video-convert.mp4 if checked)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 13:03:54 -05:00
8896206b68 Create professional DVD structure with automatic chapter markers
Major improvements to DVD authoring for professional results:

- Always concatenate multiple videos into single title (not multiple titles)
- Automatically generate chapter markers from video clips
- Chapter markers created at each scene boundary regardless of checkbox
- One title with navigable chapters instead of separate titles
- Better logging showing chapter structure and timestamps

Before: 4 videos → 4 separate titles with no chapters
After: 4 videos → 1 title with 4 chapter markers

This creates a professional DVD that matches commercial disc structure
with proper chapter navigation.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 12:05:21 -05:00
7 changed files with 72 additions and 620 deletions

View File

@ -1,411 +0,0 @@
# Main.go Modularization - Incremental Refactoring Prompt
## Current State
**Problem:** main.go is 14,116 lines (420KB) causing:
- 5+ minute builds on Windows
- Poor code maintainability
- Difficult to navigate and modify
**Goal:** Extract modules into separate files following established patterns
**Already Extracted:**
- ✅ `author_module.go` (1,421 lines) - Pattern reference
- ✅ `subtitles_module.go` (756 lines) - Pattern reference
- ✅ `inspect_module.go` (292 lines) - Pattern reference
**Remaining:** 9 modules to extract (~10,000 lines)
---
## Extraction Order (Least Important → Most Important)
Work through these **one module at a time**, testing after each extraction:
### Phase 1: Simple Modules (Start Here)
1. **filters_module.go** (~236 lines)
- Lines: ~13261-13497
- Functions: `showFiltersView()`, `buildFiltersView()`
- State fields: `filtersFile`, `filterBrightness`, `filterContrast`, etc.
- Why first: Simple UI-only, no job execution
2. **upscale_module.go** (~889 lines + job executor)
- Lines: ~13498-14387 + job executor at ~4568-5023
- Functions: `showUpscaleView()`, `buildUpscaleView()`, `executeUpscaleJob()`, AI helpers
- State fields: All `upscale*` fields (~25 fields)
- Includes: AI backend detection, model helpers
3. **thumb_module.go** (~335 lines + job executor)
- Lines: ~12837-13172 + executeThumbJob at ~4222-4264
- Functions: `showThumbView()`, `buildThumbView()`, `executeThumbJob()`
- State fields: `thumbFile`, `thumbCount`, `thumbWidth`, etc.
### Phase 2: Moderate Complexity
4. **player_module.go** (~87 lines + playSession ~450 lines)
- Lines: ~13173-13260 + playSession at ~8929-9329
- Functions: `showPlayerView()`, `buildPlayerView()`, `stopPlayer()`, entire `playSession` type
- State fields: `playerFile`, `player`, `playerReady`, `playerVolume`, etc.
- Types: `playSession`, `playerSurface`, `playSession` methods
- Note: Includes recent performance improvements
5. **compare_module.go** (~503 lines + fullscreen)
- Lines: ~12068-12571 + fullscreen at ~14277-14387
- Functions: `showCompareView()`, `buildCompareView()`, `buildCompareFullscreenView()`, `showCompareFullscreen()`
- State fields: `compareFile1`, `compareFile2`, `autoCompare`
### Phase 3: Complex Infrastructure
6. **merge_module.go** (~374 lines + job executor)
- Lines: ~2752-3126 + executeMergeJob at ~3232-3564
- Functions: `showMergeView()` (inline UI builder), `addMergeToQueue()`, `executeMergeJob()`
- State fields: `mergeClips`, `mergeFormat`, `mergeOutput`, etc.
- Types: `mergeClip` struct
- Note: UI builder is inline, needs extraction to `buildMergeView()`
7. **benchmark_module.go** (~326 lines)
- Lines: ~1938-2264 + config persistence at ~700-729
- Functions: `showBenchmark()`, `showBenchmarkHistory()`, benchmark helpers
- Types: `benchmarkConfig`, `benchmarkRun`
8. **queue_module.go** (~scattered functions)
- Functions: `showQueue()`, `refreshQueueView()`, `jobExecutor()`, `buildFFmpegCommandFromJob()`
- Lines: Various, needs gathering
### Phase 4: Most Critical (Do Last)
9. **convert_module.go** (~6,384 lines - THE BIG ONE)
- Lines: ~5683-12067
- Functions: 50+ functions including `buildConvertView()`, `showConvertView()`, all convert helpers
- State fields: All `convert*` fields, `source`, `loadedVideos`, etc.
- Types: `convertConfig`, `formatOption`
- Shared components: `buildMetadataPanel()`, `buildVideoPane()` (used by other modules)
- May need to split into multiple files if > 3000 lines
---
## Instructions for Each Module Extraction
### Step-by-Step Process
For each module (do ONE at a time):
#### 1. Create the Module File
**File:** `{module}_module.go` (e.g., `filters_module.go`)
**Template:**
```go
package main
import (
// Copy imports from main.go that this module needs
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
// ... etc
)
// Move the show{Module}View() method here
func (s *appState) show{Module}View() {
s.stopPreview()
s.lastModule = s.active
s.active = "{module}"
s.setContent(build{Module}View(s))
}
// Move the build{Module}View() function here
func build{Module}View(state *appState) fyne.CanvasObject {
// ... entire function body ...
}
// Move any helper functions specific to this module
// Move any job executor functions (execute{Module}Job)
```
#### 2. Remove from main.go
Delete the exact same functions you just moved. Use line numbers as guide.
**IMPORTANT:** Do NOT remove:
- Shared functions used by multiple modules (e.g., `moduleColor()`, `probeVideo()`)
- State fields in `appState` struct (leave all state in main.go)
- Type definitions used across modules
#### 3. Build and Test
```bash
# Must succeed
go build -o VideoTools .
# Check line count reduction
wc -l main.go {module}_module.go
# Test the module works
./VideoTools # Navigate to the module and test basic functionality
```
#### 4. Commit
```bash
git add {module}_module.go main.go
git commit -m "Extract {module} module from main.go
- Create {module}_module.go (XXX lines)
- Move show{Module}View() and build{Module}View()
- Reduce main.go by XXX lines
- All tests pass, module functions correctly
"
```
#### 5. Move to Next Module
Repeat the process for the next module in the order above.
---
## Reference Patterns
Look at these existing extracted modules for the pattern:
### Pattern 1: Simple Module (inspect_module.go)
```go
package main
import (
// Necessary imports
)
func (s *appState) showInspectView() {
s.stopPreview()
s.lastModule = s.active
s.active = "inspect"
s.setContent(buildInspectView(s))
}
func buildInspectView(state *appState) fyne.CanvasObject {
// UI building code
}
```
### Pattern 2: Module with Job Executor (subtitles_module.go)
```go
package main
import (
// Necessary imports
)
func (s *appState) showSubtitlesView() {
// ...
}
func buildSubtitlesView(state *appState) fyne.CanvasObject {
// ...
}
func (s *appState) executeSubtitlesJob(ctx context.Context, job *queue.Job, progressCallback func(float64)) error {
// Job execution logic
}
// Helper functions specific to subtitles
```
### Pattern 3: Module with Types (author_module.go)
```go
package main
import (
// ...
)
// Types specific to this module
type authorClip struct {
// ...
}
func (s *appState) showAuthorView() {
// ...
}
// Many helper functions specific to author module
```
---
## What Stays in main.go
**DO NOT MOVE these to module files:**
### Core Application
- `main()` function
- `runGUI()` function
- `type appState struct` definition (all fields stay)
- Window setup and initialization
### Shared Utilities (Used by 3+ modules)
- `moduleColor()` - Color scheme helper
- `moduleFooter()` - Footer bar builder
- `statusStrip()` - Status bar
- `probeVideo()` - Video file analysis (CRITICAL - used everywhere)
- `buildMetadataPanel()` - Used by convert and other modules
- `buildVideoPane()` - Video preview pane (used by many modules)
- `formatBitrate()`, `formatClock()`, etc. - Format helpers
### Navigation & State
- `showMainMenu()` - Main menu builder
- `setContent()` - Content switcher
- History sidebar code
- Stats bar updates
- Drop handlers
### Shared Types
- `videoSource` type and methods
- Shared constants and enums
---
## Special Cases & Gotchas
### Convert Module (Do Last!)
The convert module is massive and may need splitting:
**Option A: Single File** (if < 3000 lines after extraction)
- `convert_module.go`
**Option B: Split into Multiple Files** (if > 3000 lines)
- `convert_module.go` - Main UI and show function
- `convert_config.go` - Configuration types and persistence
- `convert_job.go` - Job execution logic
- `convert_helpers.go` - Codec/format helpers
**Shared Components:**
- `buildMetadataPanel()` and `buildVideoPane()` might need to move to `shared_ui.go` if used by many modules
### Merge Module Inline UI
The merge module has UI building inline in `showMergeView()`. You'll need to:
1. Extract inline UI to `buildMergeView()` function
2. Then follow standard pattern
### Player Module with playSession
The `playSession` type and all its methods should move to `player_module.go` together.
### Import Adjustments
Some modules might need internal package imports that aren't in main.go:
- Check for missing imports after extraction
- Run `go build` to catch import errors
- Add necessary imports to the module file
---
## Success Criteria for Each Extraction
Before moving to next module, verify:
- ✅ `go build` succeeds with no errors
- ✅ Module file has clear structure (show function, build function, helpers)
- ✅ main.go reduced by expected lines
- ✅ Module works when tested in GUI
- ✅ No duplicate code between main.go and module file
- ✅ Git commit created with clear message
- ✅ Can navigate to module and use basic features
---
## Tracking Progress
After each extraction, update this checklist:
- [ ] 1. filters_module.go (~236 lines)
- [ ] 2. upscale_module.go (~1200 lines)
- [ ] 3. thumb_module.go (~400 lines)
- [ ] 4. player_module.go (~800 lines)
- [ ] 5. compare_module.go (~550 lines)
- [ ] 6. merge_module.go (~700 lines)
- [ ] 7. benchmark_module.go (~400 lines)
- [ ] 8. queue_module.go (~500 lines)
- [ ] 9. convert_module.go (~6400 lines - may split)
**Target:** main.go from 14,116 lines → ~4,000 lines
---
## Expected Timeline
- **Simple modules (1-3):** 20-30 min each
- **Moderate modules (4-5):** 30-45 min each
- **Complex modules (6-8):** 45-60 min each
- **Convert module (9):** 2-3 hours (largest, most critical)
**Total:** ~8-12 hours of incremental work
---
## Final Build Performance Goal
After all extractions:
**Before:**
- main.go: 14,329 lines (426KB)
- Build time (Windows): 5+ minutes
**After:**
- main.go: ~4,000 lines (~120KB)
- Module files: 10-12 files (~800-1500 lines each)
- Build time (Windows): < 2 minutes (hopefully < 1 minute)
---
## Questions to Ask If Stuck
1. **"Does this function use state from multiple modules?"**
- Yes → Keep in main.go
- No → Move to module file
2. **"Is this function called by 3+ different modules?"**
- Yes → Keep in main.go as shared utility
- No → Move to the module that uses it
3. **"Is this a type used across modules?"**
- Yes → Keep type definition in main.go
- No → Move to module file
4. **"Where are the line numbers for this module?"**
- Check this document's module listing
- Use grep to find function: `grep -n "func buildXView" main.go`
---
## Emergency Rollback
If an extraction breaks the build:
```bash
# Restore main.go from backup
git checkout HEAD -- main.go
# Remove the broken module file
rm {module}_module.go
# Try again with more care
```
---
## Start Here
**First module to extract:** `filters_module.go`
1. Find lines ~13261-13497 in main.go
2. Create `filters_module.go`
3. Copy `showFiltersView()` and `buildFiltersView()`
4. Remove from main.go
5. Build, test, commit
6. Move to next module
Good luck! Take it one module at a time, test after each extraction, and the convert module will be much easier once you've established the pattern with the simpler modules.

View File

@ -1238,6 +1238,9 @@ func concatDVDMpg(inputs []string, output string) error {
"-safe", "0",
"-i", listPath,
"-c", "copy",
"-f", "dvd", // Maintain DVD format
"-muxrate", "10080000", // DVD mux rate
"-packetsize", "2048", // DVD packet size
output,
}
return runCommand(platformConfig.FFmpegPath, args)
@ -1733,7 +1736,15 @@ func (s *appState) runAuthoringPipeline(ctx context.Context, paths []string, reg
}
remuxPath := filepath.Join(workDir, fmt.Sprintf("title_%02d_remux.mpg", i+1))
remuxArgs := []string{"-fflags", "+genpts", "-i", outPath, "-c", "copy", "-f", "dvd", "-y", remuxPath}
remuxArgs := []string{
"-fflags", "+genpts",
"-i", outPath,
"-c", "copy",
"-f", "dvd",
"-muxrate", "10080000",
"-packetsize", "2048",
"-y", remuxPath,
}
if logFn != nil {
logFn(fmt.Sprintf(">> ffmpeg %s (remuxing for DVD compliance)", strings.Join(remuxArgs, " ")))
}
@ -1744,27 +1755,35 @@ func (s *appState) runAuthoringPipeline(ctx context.Context, paths []string, reg
mpgPaths = append(mpgPaths, remuxPath)
}
if len(chapters) == 0 && treatAsChapters && len(clips) > 1 {
// Generate chapters from clips if available (for professional DVD navigation)
if len(chapters) == 0 && len(clips) > 1 {
chapters = chaptersFromClips(clips)
if logFn != nil {
logFn(fmt.Sprintf("Generated %d chapter markers from video clips", len(chapters)))
}
}
// Try to extract embedded chapters from single file
if len(chapters) == 0 && len(mpgPaths) == 1 {
if embed, err := extractChaptersFromFile(paths[0]); err == nil && len(embed) > 0 {
chapters = embed
if logFn != nil {
logFn(fmt.Sprintf("Extracted %d embedded chapters from source", len(chapters)))
}
}
}
if treatAsChapters && len(mpgPaths) > 1 {
// For professional DVD: always concatenate multiple files into one title with chapters
if len(mpgPaths) > 1 {
concatPath := filepath.Join(workDir, "titles_joined.mpg")
if logFn != nil {
logFn("Concatenating chapters into a single title...")
logFn(fmt.Sprintf("Combining %d videos into single title with chapter markers...", len(mpgPaths)))
}
if err := concatDVDMpg(mpgPaths, concatPath); err != nil {
return err
return fmt.Errorf("failed to concatenate videos: %w", err)
}
mpgPaths = []string{concatPath}
}
if len(mpgPaths) > 1 {
chapters = nil
}
// Log details about encoded MPG files
if logFn != nil {
@ -1783,6 +1802,16 @@ func (s *appState) runAuthoringPipeline(ctx context.Context, paths []string, reg
return err
}
// Log chapter information
if len(chapters) > 0 {
if logFn != nil {
logFn(fmt.Sprintf("Final DVD structure: 1 title with %d chapters", len(chapters)))
for i, ch := range chapters {
logFn(fmt.Sprintf(" Chapter %d: %s at %s", i+1, ch.Title, formatChapterTime(ch.Timestamp)))
}
}
}
// Log the XML content for debugging
if xmlContent, err := os.ReadFile(xmlPath); err == nil {
logFn("Generated DVD XML:")
@ -2198,6 +2227,9 @@ func buildAuthorFFmpegArgs(inputPath, outputPath, region, aspect string, progres
"-b:a", "192k",
"-ar", "48000",
"-ac", "2",
"-f", "dvd", // DVD-compliant MPEG-PS format
"-muxrate", "10080000", // DVD mux rate (10.08 Mbps)
"-packetsize", "2048", // DVD packet size
outputPath,
)

View File

@ -198,14 +198,12 @@
### 📚 Documentation Updates
#### New Documentation Added
- `HANDBRAKE_REPLACEMENT.md` - Comprehensive modern video processing strategy
- Enhanced `TODO.md` with Lossless-Cut inspired trim module specifications
- Updated `MODULES.md` with detailed trim module implementation plan
- Enhanced `docs/README.md` with VT_Player integration links
#### Documentation Enhancements
- **Trim Module Specifications** - Detailed Lossless-Cut inspired design
- **HandBrake Parity Analysis** - Feature comparison and migration strategy
- **VT_Player Integration Notes** - Cross-project component reuse
- **Implementation Roadmap** - Clear development phases and priorities

View File

@ -1,197 +0,0 @@
# VideoTools: Modern Video Processing Strategy
## 🎯 Project Vision
VideoTools provides a **modern approach to video processing** with enhanced capabilities while maintaining simplicity and focusing on core video processing workflows.
## 📊 Modern Video Processing Features
### ✅ Core Video Processing Features (VideoTools Status)
| Feature | VideoTools Status | Notes |
|---------|-------------------|---------|
| Video transcoding | ✅ IMPLEMENTED | Enhanced with DVD/Blu-ray presets |
| Queue system | ✅ IMPLEMENTED | Advanced with job reordering and prioritization |
| Preset management | 🔄 PARTIAL | Basic presets, needs modern device profiles |
| Chapter support | 🔄 PLANNED | Auto-chapter creation in trim/merge modules |
| Multi-title support | 🔄 PLANNED | For DVD/Blu-ray sources |
| Subtitle support | 🔄 PLANNED | Advanced subtitle handling and styling |
| Audio track management | 🔄 PLANNED | Multi-track selection and processing |
| Quality control | ✅ IMPLEMENTED | Enhanced with size targets and validation |
| Device profiles | 🔄 PLANNED | Modern device optimization |
### 🚀 VideoTools Modern Advantages
| Feature | Traditional Tools | VideoTools | Advantage |
|---------|------------------|-------------|-----------|
| **Modern Architecture** | Monolithic | Modular | Extensible, maintainable |
| **Cross-Platform** | Limited | Full support | Linux, Windows parity |
| **AI Upscaling** | None | Planned | Next-gen enhancement |
| **Smart Chapters** | Manual | Auto-generation | Intelligent workflow |
| **Advanced Queue** | Basic | Enhanced | Better batch processing |
| **Lossless-Cut Style** | No | Planned | Frame-accurate trimming |
| **Blu-ray Authoring** | No | Planned | Professional workflows |
| **VT_Player Integration** | No | Planned | Unified ecosystem |
## 🎯 Core HandBrake Replacement Features
### 1. **Enhanced Convert Module** (Core Replacement)
```go
// HandBrake-equivalent transcoding with modern enhancements
type ConvertConfig struct {
// HandBrake parity features
VideoCodec string // H.264, H.265, AV1
AudioCodec string // AAC, AC3, Opus, FLAC
Quality Quality // CRF, bitrate, 2-pass
Preset string // Fast, Balanced, HQ, Archive
// VideoTools enhancements
DeviceProfile string // iPhone, Android, TV, Gaming
ContentAware bool // Auto-optimize for content type
SmartBitrate bool // Size-target encoding
AIUpscale bool // AI enhancement when upscaling
}
```
### 2. **Professional Preset System** (Enhanced)
```go
// Modern device and platform presets
type PresetCategory string
const (
PresetDevices PresetCategory = "devices" // iPhone, Android, TV
PresetPlatforms PresetCategory = "platforms" // YouTube, TikTok, Instagram
PresetQuality PresetCategory = "quality" // Fast, Balanced, HQ
PresetArchive PresetCategory = "archive" // Long-term preservation
)
// HandBrake-compatible + modern presets
- iPhone 15 Pro Max
- Samsung Galaxy S24
- PlayStation 5
- YouTube 4K HDR
- TikTok Vertical
- Instagram Reels
- Netflix 4K Profile
- Archive Master Quality
```
### 3. **Advanced Queue System** (Enhanced)
```go
// HandBrake queue with modern features
type QueueJob struct {
// HandBrake parity
Source string
Destination string
Settings ConvertConfig
Status JobStatus
// VideoTools enhancements
Priority int // Job prioritization
Dependencies []int // Job dependencies
RetryCount int // Smart retry logic
ETA time.Duration // Accurate time estimation
}
```
### 4. **Smart Title Selection** (Enhanced)
```go
// Enhanced title detection for multi-title sources
type TitleInfo struct {
ID int
Duration time.Duration
Resolution string
AudioTracks []AudioTrack
Subtitles []SubtitleTrack
Chapters []Chapter
Quality QualityMetrics
Recommended bool // AI-based recommendation
}
// Sources: DVD, Blu-ray, multi-title MKV
```
## 🔄 User Experience Strategy
### **Modern Video Processing Experience**
- **Intuitive Interface** - Clean, focused layout for common workflows
- **Smart Presets** - Content-aware and device-optimized settings
- **Efficient Queue** - Advanced batch processing with job management
- **Professional Workflows** - DVD/Blu-ray authoring, multi-format output
### **Enhanced Processing Capabilities**
- **Smart Defaults** - Content-aware optimization for better results
- **Hardware Acceleration** - GPU utilization across all platforms
- **Modern Codecs** - AV1, HEVC, VP9 with professional profiles
- **AI Features** - Intelligent upscaling and quality enhancement
## 📋 Implementation Priority
### **Phase 1: Core Modern Features** (6-8 weeks)
1. **Enhanced Convert Module** - Modern transcoding with smart optimization
2. **Professional Presets** - Device and platform-specific profiles
3. **Advanced Queue System** - Intelligent batch processing with prioritization
4. **Multi-Title Support** - DVD/Blu-ray source handling
### **Phase 2: Enhanced Workflows** (4-6 weeks)
5. **Smart Chapter System** - Auto-generation in trim/merge modules
6. **Advanced Audio Processing** - Multi-track management and conversion
7. **Comprehensive Subtitle System** - Advanced subtitle handling and styling
8. **Quality Control Tools** - Size targets and validation systems
### **Phase 3: Next-Generation Features** (6-8 weeks)
9. **AI-Powered Upscaling** - Modern enhancement and upscaling
10. **VT_Player Integration** - Unified playback and processing ecosystem
11. **Professional Blu-ray Authoring** - Complete Blu-ray workflow support
12. **Content-Aware Processing** - Intelligent optimization based on content analysis
## 🎯 Key Differentiators
### **Technical Advantages**
- **Modern Codebase** - Go language for better maintainability and performance
- **Modular Architecture** - Extensible design for future enhancements
- **Cross-Platform** - Native support on Linux and Windows
- **Hardware Acceleration** - Optimized GPU utilization across platforms
- **AI Integration** - Next-generation enhancement capabilities
### **User Experience**
- **Intuitive Interface** - Focused design for common video workflows
- **Smart Defaults** - Content-aware settings for excellent results
- **Optimized Performance** - Efficient encoding pipelines and processing
- **Real-time Feedback** - Quality metrics and progress indicators
- **Unified Ecosystem** - Integrated VT_Player for seamless workflow
### **Professional Features**
- **Broadcast Quality** - Professional standards compliance and validation
- **Advanced Workflows** - Complete DVD and Blu-ray authoring capabilities
- **Intelligent Batch Processing** - Advanced queue system with job management
- **Quality Assurance** - Built-in validation and testing tools
## 📊 Success Metrics
### **Modern Video Processing Goals**
- ✅ **Complete Feature Set** - Comprehensive video processing capabilities
- ✅ **50% Faster Encoding** - Optimized hardware utilization
- ✅ **30% Better Quality** - Smart optimization algorithms
- ✅ **Cross-Platform** - Native Linux/Windows support
### **Market Positioning**
- **Modern Video Suite** - Next-generation architecture and features
- **Professional Tool** - Beyond consumer-level capabilities
- **Intuitive Processing** - Smart defaults and user-friendly workflows
- **Ecosystem Solution** - Integrated VT_Player for seamless experience
## 🚀 User Experience Strategy
### **Launch Positioning**
- **"Modern Video Processing"** - Next-generation approach to video tools
- **"AI-Powered Enhancement"** - Intelligent upscaling and optimization
- **"Professional Video Suite"** - Comprehensive processing capabilities
- **"Cross-Platform Solution"** - Native support everywhere
### **User Onboarding**
- **Intuitive Interface** - Familiar workflows with modern enhancements
- **Smart Presets** - Content-aware settings for excellent results
- **Tutorial Integration** - Built-in guidance for advanced features
- **Workflow Examples** - Show common use cases and best practices
---
This strategy positions VideoTools as a **direct HandBrake replacement** while adding significant modern advantages and professional capabilities.

View File

@ -52,5 +52,4 @@ VideoTools is a professional-grade video processing suite with a modern GUI, cur
- [Module Feature Matrix](MODULES.md#module-coverage-summary)
- [Latest Updates](../LATEST_UPDATES.md) - Recent development changes
- [Windows Implementation](DEV14_WINDOWS_IMPLEMENTATION.md) - dev14 Windows support
- [Modern Video Processing Strategy](HANDBRAKE_REPLACEMENT.md) - Next-generation video tools approach
- [VT_Player Integration](../VT_Player/README.md) - Frame-accurate playback system

17
main.go
View File

@ -541,6 +541,7 @@ type convertConfig struct {
Mode string // Simple or Advanced
UseAutoNaming bool
AutoNameTemplate string // Template for metadata-driven naming, e.g., "<actress> - <studio> - <scene>"
AppendSuffix bool // Append "-convert" suffix to output filename (off by default)
PreserveChapters bool
// Video encoding settings
@ -610,6 +611,7 @@ func defaultConvertConfig() convertConfig {
Mode: "Simple",
UseAutoNaming: false,
AutoNameTemplate: "<actress> - <studio> - <scene>",
AppendSuffix: false, // Don't append "-convert" by default
PreserveChapters: true,
VideoCodec: "H.264",
@ -6621,6 +6623,18 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
applyAutoName(true)
}
appendSuffixCheck := widget.NewCheck("Append \"-convert\" to filename", func(checked bool) {
state.convert.AppendSuffix = checked
if !state.convert.UseAutoNaming {
applyAutoName(false)
}
// Update output hint to show the change immediately
if outputHint != nil {
outputHint.SetText(fmt.Sprintf("Output file: %s", state.convert.OutputFile()))
}
})
appendSuffixCheck.Checked = state.convert.AppendSuffix
inverseCheck := widget.NewCheck("Smart Inverse Telecine", func(checked bool) {
state.convert.InverseTelecine = checked
})
@ -8229,6 +8243,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
outputEntry,
outputHintContainer,
appendSuffixCheck,
widget.NewSeparator(),
simpleEncodingSection,
widget.NewLabelWithStyle("Target Resolution", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
@ -8291,6 +8306,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
widget.NewLabelWithStyle("Output Name", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
outputEntry,
outputHintContainer,
appendSuffixCheck,
coverDisplay,
widget.NewSeparator(),
advancedVideoEncodingBlock,
@ -8355,6 +8371,7 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
setTargetFileSize(state.convert.TargetFileSize)
autoNameCheck.SetChecked(state.convert.UseAutoNaming)
autoNameTemplate.SetText(state.convert.AutoNameTemplate)
appendSuffixCheck.SetChecked(state.convert.AppendSuffix)
outputEntry.SetText(state.convert.OutputBase)
outputHint.SetText(fmt.Sprintf("Output file: %s", state.convert.OutputFile()))
preserveChaptersCheck.SetChecked(state.convert.PreserveChapters)

View File

@ -9,6 +9,14 @@ import (
)
func defaultOutputBase(src *videoSource) string {
if src == nil {
return "converted"
}
base := strings.TrimSuffix(src.DisplayName, filepath.Ext(src.DisplayName))
return base
}
func defaultOutputBaseWithSuffix(src *videoSource) string {
if src == nil {
return "converted"
}
@ -19,7 +27,13 @@ func defaultOutputBase(src *videoSource) string {
// resolveOutputBase returns the output base for a source.
// keepExisting preserves manual edits when auto-naming is disabled; it is ignored when auto-naming is on.
func (s *appState) resolveOutputBase(src *videoSource, keepExisting bool) string {
fallback := defaultOutputBase(src)
// Use suffix if AppendSuffix is enabled
var fallback string
if s.convert.AppendSuffix {
fallback = defaultOutputBaseWithSuffix(src)
} else {
fallback = defaultOutputBase(src)
}
// Auto-naming overrides manual values.
if s.convert.UseAutoNaming && src != nil && strings.TrimSpace(s.convert.AutoNameTemplate) != "" {