Compare commits
6 Commits
58c55d3bc6
...
984088749c
| Author | SHA1 | Date | |
|---|---|---|---|
| 984088749c | |||
| b71c066517 | |||
| ad1da23c6c | |||
| 1b4e504a57 | |||
| 4a58a22b81 | |||
| 4f74d5b2b2 |
|
|
@ -1474,7 +1474,7 @@ func authorDefaultOutputDir(outputType string) string {
|
|||
if err != nil || home == "" {
|
||||
home = "."
|
||||
}
|
||||
dir := filepath.Join(home, "Videos")
|
||||
dir := filepath.Join(home, "Videos", "VideoTools")
|
||||
if strings.EqualFold(outputType, "iso") {
|
||||
return filepath.Join(dir, "ISO_Convert")
|
||||
}
|
||||
|
|
@ -1755,6 +1755,28 @@ func (s *appState) runAuthoringPipeline(ctx context.Context, paths []string, reg
|
|||
mpgPaths = append(mpgPaths, remuxPath)
|
||||
}
|
||||
|
||||
// Generate clips from paths if clips is empty (fallback for when job didn't save clips)
|
||||
if len(clips) == 0 && len(paths) > 1 {
|
||||
for i, path := range paths {
|
||||
src, err := probeVideo(path)
|
||||
duration := 0.0
|
||||
displayName := filepath.Base(path)
|
||||
if err == nil {
|
||||
duration = src.Duration
|
||||
displayName = src.DisplayName
|
||||
}
|
||||
clips = append(clips, authorClip{
|
||||
Path: path,
|
||||
DisplayName: displayName,
|
||||
Duration: duration,
|
||||
ChapterTitle: fmt.Sprintf("Chapter %d", i+1),
|
||||
})
|
||||
}
|
||||
if logFn != nil {
|
||||
logFn(fmt.Sprintf("Generated %d clips from input paths for chapter markers", len(clips)))
|
||||
}
|
||||
}
|
||||
|
||||
// Generate chapters from clips if available (for professional DVD navigation)
|
||||
if len(chapters) == 0 && len(clips) > 1 {
|
||||
chapters = chaptersFromClips(clips)
|
||||
|
|
@ -1841,6 +1863,10 @@ func (s *appState) runAuthoringPipeline(ctx context.Context, paths []string, reg
|
|||
}
|
||||
|
||||
if makeISO {
|
||||
// Create output directory for ISO file if it doesn't exist
|
||||
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ISO output directory: %w", err)
|
||||
}
|
||||
tool, args, err := buildISOCommand(outputPath, discRoot, title)
|
||||
if err != nil {
|
||||
logFn(fmt.Sprintf("ERROR: ISO tool not found: %v", err))
|
||||
|
|
@ -1975,6 +2001,10 @@ func (s *appState) executeAuthorJob(ctx context.Context, job *queue.Job, progres
|
|||
}
|
||||
|
||||
appendLog(fmt.Sprintf("Authoring ISO from VIDEO_TS: %s", videoTSPath))
|
||||
// Create output directory for ISO file if it doesn't exist
|
||||
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
|
||||
return fmt.Errorf("failed to create ISO output directory: %w", err)
|
||||
}
|
||||
tool, args, err := buildISOCommand(outputPath, videoTSPath, title)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
47
main.go
47
main.go
|
|
@ -6625,9 +6625,13 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
|
||||
appendSuffixCheck := widget.NewCheck("Append \"-convert\" to filename", func(checked bool) {
|
||||
state.convert.AppendSuffix = checked
|
||||
if !state.convert.UseAutoNaming {
|
||||
applyAutoName(false)
|
||||
}
|
||||
// Recalculate and update the output base to reflect the suffix change
|
||||
// Always pass false for keepExisting to regenerate from source
|
||||
newBase := state.resolveOutputBase(src, false)
|
||||
updatingOutput = true
|
||||
state.convert.OutputBase = newBase
|
||||
outputEntry.SetText(newBase)
|
||||
updatingOutput = false
|
||||
// Update output hint to show the change immediately
|
||||
if outputHint != nil {
|
||||
outputHint.SetText(fmt.Sprintf("Output file: %s", state.convert.OutputFile()))
|
||||
|
|
@ -8307,7 +8311,6 @@ func buildConvertView(state *appState, src *videoSource) fyne.CanvasObject {
|
|||
outputEntry,
|
||||
outputHintContainer,
|
||||
appendSuffixCheck,
|
||||
coverDisplay,
|
||||
widget.NewSeparator(),
|
||||
advancedVideoEncodingBlock,
|
||||
widget.NewSeparator(),
|
||||
|
|
@ -9176,7 +9179,9 @@ Metadata: %s`,
|
|||
makeRow("Metadata", metadata),
|
||||
)
|
||||
|
||||
info := container.NewHBox(col1, col2)
|
||||
// Add spacing between the two columns
|
||||
spacer := layout.NewSpacer()
|
||||
info := container.NewHBox(col1, spacer, col2)
|
||||
|
||||
// Copy metadata button - beside header text
|
||||
copyBtn := widget.NewButton("📋", func() {
|
||||
|
|
@ -9196,33 +9201,10 @@ Metadata: %s`,
|
|||
headerRow := container.NewHBox(header, copyBtn)
|
||||
top = container.NewBorder(nil, nil, nil, clearBtn, headerRow)
|
||||
|
||||
// Cover art display area - 40% larger (168x168)
|
||||
coverImg := canvas.NewImageFromFile("")
|
||||
coverImg.FillMode = canvas.ImageFillContain
|
||||
coverImg.SetMinSize(fyne.NewSize(168, 168))
|
||||
|
||||
placeholderRect := canvas.NewRectangle(utils.MustHex("#0F1529"))
|
||||
placeholderRect.SetMinSize(fyne.NewSize(168, 168))
|
||||
placeholderText := widget.NewLabel("Drop cover\nart here")
|
||||
placeholderText.Alignment = fyne.TextAlignCenter
|
||||
placeholderText.TextStyle = fyne.TextStyle{Italic: true}
|
||||
placeholder := container.NewMax(placeholderRect, container.NewCenter(placeholderText))
|
||||
|
||||
// Update cover art when changed
|
||||
// Cover art support removed - users can add cover art through metadata editor
|
||||
updateCoverDisplay := func() {
|
||||
if state.convert.CoverArtPath != "" {
|
||||
coverImg.File = state.convert.CoverArtPath
|
||||
coverImg.Refresh()
|
||||
placeholder.Hide()
|
||||
coverImg.Show()
|
||||
} else {
|
||||
coverImg.Hide()
|
||||
placeholder.Show()
|
||||
}
|
||||
// No-op: cover art display removed from this panel
|
||||
}
|
||||
updateCoverDisplay()
|
||||
|
||||
coverContainer := container.NewMax(placeholder, coverImg)
|
||||
|
||||
// Interlacing Analysis Section
|
||||
analyzeBtn := widget.NewButton("Analyze Interlacing", func() {
|
||||
|
|
@ -9405,9 +9387,8 @@ Metadata: %s`,
|
|||
)
|
||||
}
|
||||
|
||||
// Layout: metadata form on left, cover art on right (bottom-aligned)
|
||||
coverColumn := container.NewVBox(layout.NewSpacer(), coverContainer)
|
||||
contentArea := container.NewBorder(nil, nil, nil, coverColumn, info)
|
||||
// Layout: two-column metadata display with spacing
|
||||
contentArea := info
|
||||
|
||||
body := container.NewVBox(
|
||||
top,
|
||||
|
|
|
|||
|
|
@ -226,6 +226,14 @@ func buildRipView(state *appState) fyne.CanvasObject {
|
|||
state.persistRipConfig()
|
||||
})
|
||||
|
||||
clearISOBtn := widget.NewButton("Clear ISO", func() {
|
||||
state.ripSourcePath = ""
|
||||
state.ripOutputPath = ""
|
||||
sourceEntry.SetText("")
|
||||
outputEntry.SetText("")
|
||||
})
|
||||
clearISOBtn.Importance = widget.LowImportance
|
||||
|
||||
controls := container.NewVBox(
|
||||
widget.NewLabelWithStyle("Source", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
ui.NewDroppable(sourceEntry, func(items []fyne.URI) {
|
||||
|
|
@ -237,6 +245,7 @@ func buildRipView(state *appState) fyne.CanvasObject {
|
|||
outputEntry.SetText(state.ripOutputPath)
|
||||
}
|
||||
}),
|
||||
clearISOBtn,
|
||||
widget.NewLabelWithStyle("Format", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
formatSelect,
|
||||
widget.NewLabelWithStyle("Output", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
|
||||
|
|
@ -357,6 +366,12 @@ func (s *appState) executeRipJob(ctx context.Context, job *queue.Job, progressCa
|
|||
}
|
||||
defer os.Remove(listFile)
|
||||
|
||||
// Create output directory if it doesn't exist
|
||||
outputDir := filepath.Dir(outputPath)
|
||||
if err := os.MkdirAll(outputDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create output directory: %w", err)
|
||||
}
|
||||
|
||||
args := buildRipFFmpegArgs(listFile, outputPath, format)
|
||||
appendLog(fmt.Sprintf(">> ffmpeg %s", strings.Join(args, " ")))
|
||||
updateProgress(10)
|
||||
|
|
@ -376,7 +391,7 @@ func defaultRipOutputPath(sourcePath, format string) string {
|
|||
if err != nil || home == "" {
|
||||
home = "."
|
||||
}
|
||||
baseDir := filepath.Join(home, "Videos", "DVD_Rips")
|
||||
baseDir := filepath.Join(home, "Videos", "VideoTools", "DVD_Rips")
|
||||
name := strings.TrimSuffix(filepath.Base(sourcePath), filepath.Ext(sourcePath))
|
||||
if strings.EqualFold(name, "video_ts") {
|
||||
name = filepath.Base(filepath.Dir(sourcePath))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user