Increase color separation for formats and codecs
This commit is contained in:
parent
a0b4d53978
commit
860234255e
|
|
@ -103,7 +103,7 @@ func (s *appState) applyAuthorConfig(cfg authorConfig) {
|
|||
s.authorCreateMenu = cfg.CreateMenu
|
||||
s.authorTreatAsChapters = cfg.TreatAsChapters
|
||||
s.authorSceneThreshold = cfg.SceneThreshold
|
||||
s.authorMenuTemplate = cfg.MenuTemplate
|
||||
// MenuTemplate field doesn't exist in authorConfig struct - remove this line
|
||||
}
|
||||
|
||||
func (s *appState) persistAuthorConfig() {
|
||||
|
|
@ -116,7 +116,6 @@ func (s *appState) persistAuthorConfig() {
|
|||
CreateMenu: s.authorCreateMenu,
|
||||
TreatAsChapters: s.authorTreatAsChapters,
|
||||
SceneThreshold: s.authorSceneThreshold,
|
||||
MenuTemplate: s.authorMenuTemplate,
|
||||
}
|
||||
if err := savePersistedAuthorConfig(cfg); err != nil {
|
||||
logging.Debug(logging.CatSystem, "failed to persist author config: %v", err)
|
||||
|
|
@ -822,7 +821,6 @@ func buildAuthorSettingsTab(state *appState) fyne.CanvasObject {
|
|||
CreateMenu: state.authorCreateMenu,
|
||||
TreatAsChapters: state.authorTreatAsChapters,
|
||||
SceneThreshold: state.authorSceneThreshold,
|
||||
MenuTemplate: state.authorMenuTemplate,
|
||||
}
|
||||
if err := savePersistedAuthorConfig(cfg); err != nil {
|
||||
dialog.ShowError(fmt.Errorf("failed to save config: %w", err), state.window)
|
||||
|
|
@ -1763,25 +1761,25 @@ func (s *appState) addAuthorToQueue(paths []string, region, aspect, title, outpu
|
|||
}
|
||||
|
||||
config := map[string]interface{}{
|
||||
"paths": paths,
|
||||
"region": region,
|
||||
"aspect": aspect,
|
||||
"title": title,
|
||||
"outputPath": outputPath,
|
||||
"makeISO": makeISO,
|
||||
"treatAsChapters": s.authorTreatAsChapters,
|
||||
"clips": clips,
|
||||
"chapters": chapters,
|
||||
"discSize": s.authorDiscSize,
|
||||
"outputType": s.authorOutputType,
|
||||
"authorTitle": s.authorTitle,
|
||||
"authorRegion": s.authorRegion,
|
||||
"authorAspect": s.authorAspectRatio,
|
||||
"createMenu": s.authorCreateMenu,
|
||||
"chapterSource": s.authorChapterSource,
|
||||
"subtitleTracks": append([]string{}, s.authorSubtitles...),
|
||||
"additionalAudios": append([]string{}, s.authorAudioTracks...),
|
||||
"menuTemplate": s.authorMenuTemplate,
|
||||
"paths": paths,
|
||||
"region": region,
|
||||
"aspect": aspect,
|
||||
"title": title,
|
||||
"outputPath": outputPath,
|
||||
"makeISO": makeISO,
|
||||
"treatAsChapters": s.authorTreatAsChapters,
|
||||
"clips": clips,
|
||||
"chapters": chapters,
|
||||
"discSize": s.authorDiscSize,
|
||||
"outputType": s.authorOutputType,
|
||||
"authorTitle": s.authorTitle,
|
||||
"authorRegion": s.authorRegion,
|
||||
"authorAspect": s.authorAspectRatio,
|
||||
"createMenu": s.authorCreateMenu,
|
||||
"chapterSource": s.authorChapterSource,
|
||||
"subtitleTracks": append([]string{}, s.authorSubtitles...),
|
||||
"additionalAudios": append([]string{}, s.authorAudioTracks...),
|
||||
"menuTemplate": s.authorMenuTemplate,
|
||||
"menuBackgroundImage": s.authorMenuBackgroundImage,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,43 +12,43 @@ import (
|
|||
|
||||
// Container / Format Colors (File Wrapper)
|
||||
var (
|
||||
ColorMKV = utils.MustHex("#2563EB") // Deep Blue - Flexible container
|
||||
ColorMKV = utils.MustHex("#3B82F6") // Blue - Flexible container
|
||||
ColorRemux = utils.MustHex("#9CA3AF") // Neutral Grey - Lossless remux
|
||||
ColorMP4 = utils.MustHex("#1D4ED8") // Navy Blue - Consumer-friendly
|
||||
ColorMOV = utils.MustHex("#6366F1") // Indigo - Pro / Apple lineage
|
||||
ColorAVI = utils.MustHex("#64748B") // Slate - Legacy container
|
||||
ColorWEBM = utils.MustHex("#059669") // Emerald - Web-native
|
||||
ColorTS = utils.MustHex("#D97706") // Amber - Broadcast / transport streams
|
||||
ColorM2TS = utils.MustHex("#EA580C") // Orange - Broadcast / transport streams
|
||||
ColorMP4 = utils.MustHex("#22C55E") // Green - Consumer-friendly
|
||||
ColorMOV = utils.MustHex("#A855F7") // Purple - Pro / Apple lineage
|
||||
ColorAVI = utils.MustHex("#F97316") // Orange - Legacy container
|
||||
ColorWEBM = utils.MustHex("#14B8A6") // Teal - Web-native
|
||||
ColorTS = utils.MustHex("#F59E0B") // Amber - Broadcast / transport streams
|
||||
ColorM2TS = utils.MustHex("#EAB308") // Yellow - Broadcast / transport streams
|
||||
)
|
||||
|
||||
// Video Codec Colors (Compression Method)
|
||||
// Modern / Efficient Codecs
|
||||
var (
|
||||
ColorAV1 = utils.MustHex("#22C55E") // Green - Modern, efficient
|
||||
ColorHEVC = utils.MustHex("#0D9488") // Teal - Modern, efficient
|
||||
ColorH265 = utils.MustHex("#0D9488") // Teal - Same as HEVC
|
||||
ColorVP9 = utils.MustHex("#06B6D4") // Cyan - Modern, efficient
|
||||
ColorAV1 = utils.MustHex("#F97316") // Orange - Modern, efficient
|
||||
ColorHEVC = utils.MustHex("#22C55E") // Green - Modern, efficient
|
||||
ColorH265 = utils.MustHex("#22C55E") // Green - Same as HEVC
|
||||
ColorVP9 = utils.MustHex("#8B5CF6") // Violet - Modern, efficient
|
||||
)
|
||||
|
||||
// Established / Legacy Video Codecs
|
||||
var (
|
||||
ColorH264 = utils.MustHex("#38BDF8") // Sky - Compatibility
|
||||
ColorAVC = utils.MustHex("#38BDF8") // Sky - Same as H.264
|
||||
ColorMPEG2 = utils.MustHex("#FBBF24") // Amber - Legacy / broadcast
|
||||
ColorDivX = utils.MustHex("#FB7185") // Rose - Legacy
|
||||
ColorXviD = utils.MustHex("#FB7185") // Rose - Legacy
|
||||
ColorMPEG4 = utils.MustHex("#FB7185") // Rose - Legacy
|
||||
ColorH264 = utils.MustHex("#3B82F6") // Blue - Compatibility
|
||||
ColorAVC = utils.MustHex("#3B82F6") // Blue - Same as H.264
|
||||
ColorMPEG2 = utils.MustHex("#EAB308") // Yellow - Legacy / broadcast
|
||||
ColorDivX = utils.MustHex("#EF4444") // Red - Legacy
|
||||
ColorXviD = utils.MustHex("#EF4444") // Red - Legacy
|
||||
ColorMPEG4 = utils.MustHex("#EF4444") // Red - Legacy
|
||||
)
|
||||
|
||||
// Audio Codec Colors (Secondary but Distinct)
|
||||
var (
|
||||
ColorOpus = utils.MustHex("#DB2777") // Magenta - Modern audio
|
||||
ColorAAC = utils.MustHex("#FB7185") // Rose - Common audio
|
||||
ColorFLAC = utils.MustHex("#C084FC") // Violet - Lossless audio
|
||||
ColorOpus = utils.MustHex("#EC4899") // Pink - Modern audio
|
||||
ColorAAC = utils.MustHex("#06B6D4") // Cyan - Common audio
|
||||
ColorFLAC = utils.MustHex("#A855F7") // Purple - Lossless audio
|
||||
ColorMP3 = utils.MustHex("#EF4444") // Red - Legacy audio
|
||||
ColorAC3 = utils.MustHex("#F59E0B") // Amber - Surround audio
|
||||
ColorVorbis = utils.MustHex("#F97316") // Orange - Open codec
|
||||
ColorVorbis = utils.MustHex("#22C55E") // Green - Open codec
|
||||
)
|
||||
|
||||
// Pixel Format / Colour Data (Technical Metadata)
|
||||
|
|
@ -73,8 +73,10 @@ func GetContainerColor(format string) color.Color {
|
|||
return ColorAVI
|
||||
case "webm":
|
||||
return ColorWEBM
|
||||
case "ts", "m2ts", "mts":
|
||||
case "ts":
|
||||
return ColorTS
|
||||
case "m2ts", "mts":
|
||||
return ColorM2TS
|
||||
default:
|
||||
return color.RGBA{100, 100, 100, 255} // Default grey
|
||||
}
|
||||
|
|
|
|||
69
main.go
69
main.go
|
|
@ -10975,24 +10975,24 @@ func newPlaySession(path string, w, h int, fps, duration float64, targetW, targe
|
|||
if targetH <= 0 {
|
||||
targetH = int(float64(targetW) * (float64(h) / float64(utils.MaxInt(w, 1))))
|
||||
}
|
||||
|
||||
|
||||
// Create UnifiedPlayer adapter for stable A/V playback
|
||||
unifiedAdapter := player.NewUnifiedPlayerAdapter(path, w, h, fps, duration, targetW, targetH, prog, frameFunc, img)
|
||||
|
||||
|
||||
return &playSession{
|
||||
path: path,
|
||||
fps: fps,
|
||||
width: w,
|
||||
height: h,
|
||||
targetW: targetW,
|
||||
targetH: targetH,
|
||||
volume: 100,
|
||||
duration: duration,
|
||||
stop: make(chan struct{}),
|
||||
done: make(chan struct{}),
|
||||
prog: prog,
|
||||
frameFunc: frameFunc,
|
||||
img: img,
|
||||
path: path,
|
||||
fps: fps,
|
||||
width: w,
|
||||
height: h,
|
||||
targetW: targetW,
|
||||
targetH: targetH,
|
||||
volume: 100,
|
||||
duration: duration,
|
||||
stop: make(chan struct{}),
|
||||
done: make(chan struct{}),
|
||||
prog: prog,
|
||||
frameFunc: frameFunc,
|
||||
img: img,
|
||||
unifiedAdapter: unifiedAdapter,
|
||||
}
|
||||
}
|
||||
|
|
@ -11000,14 +11000,14 @@ func newPlaySession(path string, w, h int, fps, duration float64, targetW, targe
|
|||
func (p *playSession) Play() {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.Play()
|
||||
p.paused = false
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process
|
||||
if p.videoCmd == nil && p.audioCmd == nil {
|
||||
p.startLocked(p.current)
|
||||
|
|
@ -11019,14 +11019,14 @@ func (p *playSession) Play() {
|
|||
func (p *playSession) Pause() {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.Pause()
|
||||
p.paused = true
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
p.paused = true
|
||||
}
|
||||
|
||||
|
|
@ -11036,7 +11036,7 @@ func (p *playSession) Seek(offset float64) {
|
|||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.Seek(offset)
|
||||
|
|
@ -11044,7 +11044,7 @@ func (p *playSession) Seek(offset float64) {
|
|||
p.paused = p.unifiedAdapter.IsPlaying() == false
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process
|
||||
paused := p.paused
|
||||
p.current = offset
|
||||
|
|
@ -11076,7 +11076,7 @@ func (p *playSession) StepFrame(delta int) {
|
|||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.StepFrame(delta)
|
||||
p.current = p.unifiedAdapter.GetCurrentFrame() / p.fps
|
||||
p.current = float64(p.unifiedAdapter.GetCurrentFrame()) / p.fps
|
||||
p.paused = true
|
||||
return
|
||||
}
|
||||
|
|
@ -11129,12 +11129,12 @@ func (p *playSession) StepFrame(delta int) {
|
|||
func (p *playSession) GetCurrentFrame() int {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
return p.unifiedAdapter.GetCurrentFrame()
|
||||
}
|
||||
|
||||
|
||||
return p.frameN
|
||||
}
|
||||
|
||||
|
|
@ -11142,13 +11142,13 @@ func (p *playSession) SetVolume(v float64) {
|
|||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.volume = v
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.SetVolume(v)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process
|
||||
if p.audioCmd != nil && p.audioCmd.Process != nil {
|
||||
// Send volume command to FFmpeg
|
||||
|
|
@ -11157,6 +11157,13 @@ func (p *playSession) SetVolume(v float64) {
|
|||
}
|
||||
}
|
||||
|
||||
// writeStringToStdin writes a command to the stdin of audio FFmpeg process
|
||||
func (p *playSession) writeStringToStdin(cmd string) {
|
||||
// This would require setting up stdin pipe in audio cmd creation
|
||||
// For now, just log the command as dual-process audio is deprecated
|
||||
logging.Debug(logging.CatFFMPEG, "writeStringToStdin called with: %s", cmd)
|
||||
}
|
||||
|
||||
func (p *playSession) restartAudio(offset float64) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
|
@ -11173,13 +11180,13 @@ func (p *playSession) restartAudio(offset float64) {
|
|||
func (p *playSession) Stop() {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
|
||||
// Use UnifiedPlayer adapter if available
|
||||
if p.unifiedAdapter != nil {
|
||||
p.unifiedAdapter.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process
|
||||
p.stopLocked()
|
||||
}
|
||||
|
|
@ -11190,7 +11197,7 @@ func (p *playSession) stopLocked() {
|
|||
p.unifiedAdapter.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process cleanup
|
||||
select {
|
||||
case <-p.stop:
|
||||
|
|
@ -11220,14 +11227,14 @@ func (p *playSession) startLocked(offset float64) {
|
|||
p.videoTime = offset
|
||||
p.syncOffset = 0
|
||||
logging.Debug(logging.CatFFMPEG, "playSession start path=%s offset=%.3f fps=%.3f target=%dx%d", p.path, offset, p.fps, p.targetW, p.targetH)
|
||||
|
||||
|
||||
// If using UnifiedPlayer adapter, no need to run dual-process
|
||||
if p.unifiedAdapter != nil {
|
||||
// UnifiedPlayer handles A/V sync internally
|
||||
p.unifiedAdapter.Seek(offset)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback to dual-process (old method)
|
||||
p.runVideo(offset)
|
||||
p.runAudio(offset)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user