VideoTools/internal/ui/colors.go
Stu Leak 85366a7164 feat: implement unified FFmpeg player and fix critical build issues
🎯 Major Improvements:
• Unified FFmpeg Player: Rock-solid A/V sync with frame-accurate seeking
• Import Standardization: Convert to absolute module imports across codebase
• Build Fixes: Resolve critical syntax errors and compilation issues
• Code Cleanup: Remove unused code and fix variable references

🔧 Technical Changes:
• Fixed pipe initialization in unified player (internal/player/unified_ffmpeg_player.go)
• Replaced platformConfig references with utils.GetFFmpegPath() calls
• Added platform-specific exec utilities (exec_unix.go, exec_windows.go)
• Enhanced UI components with improved color handling
• Fixed missing closing brace in buildMetadataPanel function

🐛 Critical Fixes:
• Resolved "unexpected name buildVideoPane, expected (" syntax error
• Fixed undefined variable references (start → sampleStart)
• Removed calls to non-existent ColoredSelect Enable/Disable methods
• Corrected import paths from relative to absolute module references

📊 Impact:
+470 insertions, -951 deletions
• Eliminates blocking A/V synchronization issues
• Enables advanced video enhancement feature development
• Establishes consistent module architecture
• Codebase now builds and runs successfully

This commit establishes the foundation for Phase 2 enhancement features
by providing rock-solid video playback capabilities.
2026-01-02 01:02:07 -05:00

202 lines
5.9 KiB
Go

package ui
import (
"image/color"
"strings"
"git.leaktechnologies.dev/stu/VideoTools/internal/utils"
)
// Semantic Color System for VideoTools
// Based on professional NLE and broadcast tooling conventions
// Container / Format Colors (File Wrapper)
var (
ColorMKV = utils.MustHex("#00B3B3") // Teal / Cyan - Neutral, modern, flexible container
ColorRemux = utils.MustHex("#06B6D4") // Cyan-Glow - Lossless remux (no re-encoding)
ColorMP4 = utils.MustHex("#3B82F6") // Blue - Widely recognised, consumer-friendly
ColorMOV = utils.MustHex("#6366F1") // Indigo - Pro / Apple / QuickTime lineage
ColorAVI = utils.MustHex("#64748B") // Grey-Blue - Legacy container
ColorWEBM = utils.MustHex("#22C55E") // Green-Teal - Web-native
ColorTS = utils.MustHex("#F59E0B") // Amber - Broadcast / transport streams
ColorM2TS = utils.MustHex("#F59E0B") // Amber - Broadcast / transport streams
)
// Video Codec Colors (Compression Method)
// Modern / Efficient Codecs
var (
ColorAV1 = utils.MustHex("#10B981") // Emerald - Modern, efficient
ColorHEVC = utils.MustHex("#84CC16") // Lime-Green - Modern, efficient
ColorH265 = utils.MustHex("#84CC16") // Lime-Green - Same as HEVC
ColorVP9 = utils.MustHex("#22D3EE") // Green-Cyan - Modern, efficient
)
// Established / Legacy Video Codecs
var (
ColorH264 = utils.MustHex("#38BDF8") // Sky Blue - Compatibility
ColorAVC = utils.MustHex("#38BDF8") // Sky Blue - Same as H.264
ColorMPEG2 = utils.MustHex("#EAB308") // Yellow-Amber - Legacy / broadcast
ColorDivX = utils.MustHex("#FB923C") // Muted Orange - Legacy
ColorXviD = utils.MustHex("#FB923C") // Muted Orange - Legacy
ColorMPEG4 = utils.MustHex("#FB923C") // Muted Orange - Legacy
)
// Audio Codec Colors (Secondary but Distinct)
var (
ColorOpus = utils.MustHex("#8B5CF6") // Violet - Modern audio
ColorAAC = utils.MustHex("#7C3AED") // Purple-Blue - Common audio
ColorFLAC = utils.MustHex("#EC4899") // Magenta - Lossless audio
ColorMP3 = utils.MustHex("#F43F5E") // Rose - Legacy audio
ColorAC3 = utils.MustHex("#F97316") // Orange-Red - Surround audio
ColorVorbis = utils.MustHex("#A855F7") // Purple - Open codec
)
// Pixel Format / Colour Data (Technical Metadata)
var (
ColorYUV420P = utils.MustHex("#94A3B8") // Slate - Standard
ColorYUV422P = utils.MustHex("#64748B") // Slate-Blue - Intermediate
ColorYUV444P = utils.MustHex("#475569") // Steel - High quality
ColorHDR = utils.MustHex("#06B6D4") // Cyan-Glow - HDR content
ColorSDR = utils.MustHex("#9CA3AF") // Neutral Grey - SDR content
)
// GetContainerColor returns the semantic color for a container format
func GetContainerColor(format string) color.Color {
switch format {
case "mkv", "matroska":
return ColorMKV
case "mp4", "m4v":
return ColorMP4
case "mov", "quicktime":
return ColorMOV
case "avi":
return ColorAVI
case "webm":
return ColorWEBM
case "ts", "m2ts", "mts":
return ColorTS
default:
return color.RGBA{100, 100, 100, 255} // Default grey
}
}
// GetVideoCodecColor returns the semantic color for a video codec
func GetVideoCodecColor(codec string) color.Color {
switch codec {
case "av1":
return ColorAV1
case "hevc", "h265", "h.265":
return ColorHEVC
case "vp9":
return ColorVP9
case "h264", "avc", "h.264":
return ColorH264
case "mpeg2":
return ColorMPEG2
case "divx", "xvid", "mpeg4":
return ColorDivX
default:
return color.RGBA{100, 100, 100, 255} // Default grey
}
}
// GetAudioCodecColor returns the semantic color for an audio codec
func GetAudioCodecColor(codec string) color.Color {
switch codec {
case "opus":
return ColorOpus
case "aac":
return ColorAAC
case "flac":
return ColorFLAC
case "mp3":
return ColorMP3
case "ac3":
return ColorAC3
case "vorbis":
return ColorVorbis
default:
return color.RGBA{100, 100, 100, 255} // Default grey
}
}
// GetPixelFormatColor returns the semantic color for a pixel format
func GetPixelFormatColor(pixfmt string) color.Color {
switch pixfmt {
case "yuv420p", "yuv420p10le":
return ColorYUV420P
case "yuv422p", "yuv422p10le":
return ColorYUV422P
case "yuv444p", "yuv444p10le":
return ColorYUV444P
default:
return ColorSDR
}
}
// BuildFormatColorMap creates a color map for format labels
// Parses labels like "MKV (AV1)" and returns appropriate container color
func BuildFormatColorMap(formatLabels []string) map[string]color.Color {
colorMap := make(map[string]color.Color)
for _, label := range formatLabels {
// Parse format from label (e.g., "MKV (AV1)" -> "mkv")
parts := strings.Split(label, " ")
if len(parts) > 0 {
format := strings.ToLower(parts[0])
// Special case for Remux
if strings.Contains(strings.ToUpper(label), "REMUX") {
colorMap[label] = ColorRemux
continue
}
colorMap[label] = GetContainerColor(format)
}
}
return colorMap
}
// BuildVideoCodecColorMap creates a color map for video codec options
func BuildVideoCodecColorMap(codecs []string) map[string]color.Color {
colorMap := make(map[string]color.Color)
for _, codec := range codecs {
switch codec {
case "H.264":
colorMap[codec] = ColorH264
case "H.265":
colorMap[codec] = ColorHEVC
case "VP9":
colorMap[codec] = ColorVP9
case "AV1":
colorMap[codec] = ColorAV1
case "MPEG-2":
colorMap[codec] = ColorMPEG2
case "Copy":
colorMap[codec] = ColorRemux // Use remux color for copy
default:
colorMap[codec] = color.RGBA{100, 100, 100, 255}
}
}
return colorMap
}
// BuildAudioCodecColorMap creates a color map for audio codec options
func BuildAudioCodecColorMap(codecs []string) map[string]color.Color {
colorMap := make(map[string]color.Color)
for _, codec := range codecs {
switch codec {
case "AAC":
colorMap[codec] = ColorAAC
case "Opus":
colorMap[codec] = ColorOpus
case "MP3":
colorMap[codec] = ColorMP3
case "FLAC":
colorMap[codec] = ColorFLAC
case "Copy":
colorMap[codec] = ColorRemux // Use remux color for copy
default:
colorMap[codec] = color.RGBA{100, 100, 100, 255}
}
}
return colorMap
}