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>
This commit is contained in:
parent
03569cd813
commit
8896206b68
|
|
@ -1744,27 +1744,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 +1791,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:")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user