Fix metadata display and improve ISO extraction support

**Metadata Panel Fix:**
- Simplified makeRow layout to properly display values
- Changed from complex Border layout to simple HBox
- Metadata values now visible in Convert module

**RIP Module Improvements:**
- Added mount-based ISO extraction for UDF ISOs
- Added 7z extraction fallback
- Prioritizes xorriso > 7z > bsdtar for ISO extraction
- Handles both ISO9660 and UDF format DVDs

**Installation Script:**
- Updated all package managers to install xorriso
- Ensures proper UDF ISO support when disc modules enabled
- apt/dnf/zypper now install xorriso instead of genisoimage

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Stu Leak 2025-12-30 21:07:50 -05:00
parent a1a0a653e6
commit 34cf6382cc
3 changed files with 77 additions and 8 deletions

View File

@ -9148,8 +9148,8 @@ Metadata: %s`,
keyLabel := widget.NewLabel(key + ":")
keyLabel.TextStyle = fyne.TextStyle{Bold: true}
valueLabel := widget.NewLabel(value)
valueLabel.Wrapping = fyne.TextTruncate
return container.NewBorder(nil, nil, keyLabel, nil, container.NewHBox(layout.NewSpacer(), valueLabel))
valueLabel.Wrapping = fyne.TextWrapWord
return container.NewHBox(keyLabel, valueLabel)
}
// Organize metadata into a compact two-column grid

View File

@ -450,11 +450,18 @@ func resolveVideoTSPath(path string) (string, func(), error) {
return "", nil, fmt.Errorf("no VIDEO_TS folder found in %s", path)
}
if strings.HasSuffix(strings.ToLower(path), ".iso") {
// Try mount-based extraction first (works for UDF ISOs)
videoTS, cleanup, err := tryMountISO(path)
if err == nil {
return videoTS, cleanup, nil
}
// Fall back to extraction tools
tempDir, err := os.MkdirTemp(utils.TempDir(), "videotools-iso-")
if err != nil {
return "", nil, fmt.Errorf("failed to create temp dir: %w", err)
}
cleanup := func() {
cleanup = func() {
_ = os.RemoveAll(tempDir)
}
tool, args, err := buildISOExtractCommand(path, tempDir)
@ -466,7 +473,7 @@ func resolveVideoTSPath(path string) (string, func(), error) {
cleanup()
return "", nil, err
}
videoTS := filepath.Join(tempDir, "VIDEO_TS")
videoTS = filepath.Join(tempDir, "VIDEO_TS")
if info, err := os.Stat(videoTS); err == nil && info.IsDir() {
return videoTS, cleanup, nil
}
@ -476,14 +483,76 @@ func resolveVideoTSPath(path string) (string, func(), error) {
return "", nil, fmt.Errorf("unsupported source: %s", path)
}
// tryMountISO attempts to mount the ISO and copy VIDEO_TS to a temp directory
func tryMountISO(isoPath string) (string, func(), error) {
// Create mount point
mountPoint, err := os.MkdirTemp(utils.TempDir(), "videotools-mount-")
if err != nil {
return "", nil, fmt.Errorf("failed to create mount point: %w", err)
}
// Try to mount the ISO
mountCmd := exec.Command("mount", "-o", "loop,ro", isoPath, mountPoint)
if err := mountCmd.Run(); err != nil {
os.RemoveAll(mountPoint)
return "", nil, fmt.Errorf("mount failed: %w", err)
}
// Check if VIDEO_TS exists
videoTSMounted := filepath.Join(mountPoint, "VIDEO_TS")
if info, err := os.Stat(videoTSMounted); err != nil || !info.IsDir() {
exec.Command("umount", mountPoint).Run()
os.RemoveAll(mountPoint)
return "", nil, fmt.Errorf("VIDEO_TS not found in mounted ISO")
}
// Copy VIDEO_TS to temp directory
tempDir, err := os.MkdirTemp(utils.TempDir(), "videotools-iso-")
if err != nil {
exec.Command("umount", mountPoint).Run()
os.RemoveAll(mountPoint)
return "", nil, fmt.Errorf("failed to create temp dir: %w", err)
}
// Use cp to copy VIDEO_TS
cpCmd := exec.Command("cp", "-r", videoTSMounted, tempDir)
if err := cpCmd.Run(); err != nil {
exec.Command("umount", mountPoint).Run()
os.RemoveAll(mountPoint)
os.RemoveAll(tempDir)
return "", nil, fmt.Errorf("copy failed: %w", err)
}
// Unmount and clean up mount point
exec.Command("umount", mountPoint).Run()
os.RemoveAll(mountPoint)
// Return path to copied VIDEO_TS
videoTS := filepath.Join(tempDir, "VIDEO_TS")
cleanup := func() {
_ = os.RemoveAll(tempDir)
}
return videoTS, cleanup, nil
}
func buildISOExtractCommand(isoPath, destDir string) (string, []string, error) {
// Try xorriso first (best for UDF and ISO9660)
if _, err := exec.LookPath("xorriso"); err == nil {
return "xorriso", []string{"-osirrox", "on", "-indev", isoPath, "-extract", "/VIDEO_TS", destDir}, nil
}
// Try 7z (works well with both UDF and ISO9660)
if _, err := exec.LookPath("7z"); err == nil {
return "7z", []string{"x", "-o" + destDir, isoPath, "VIDEO_TS"}, nil
}
// Try bsdtar (works with ISO9660, may fail on UDF)
if _, err := exec.LookPath("bsdtar"); err == nil {
return "bsdtar", []string{"-C", destDir, "-xf", isoPath, "VIDEO_TS"}, nil
}
return "", nil, fmt.Errorf("no ISO extraction tool found (install xorriso or bsdtar)")
return "", nil, fmt.Errorf("no ISO extraction tool found (install xorriso, 7z, or bsdtar)")
}
type vobSet struct {

View File

@ -190,13 +190,13 @@ else
if [ "$SKIP_DVD_TOOLS" = true ]; then
sudo apt-get install -y ffmpeg
else
sudo apt-get install -y ffmpeg dvdauthor genisoimage
sudo apt-get install -y ffmpeg dvdauthor xorriso
fi
elif command -v dnf &> /dev/null; then
if [ "$SKIP_DVD_TOOLS" = true ]; then
sudo dnf install -y ffmpeg
else
sudo dnf install -y ffmpeg dvdauthor genisoimage
sudo dnf install -y ffmpeg dvdauthor xorriso
fi
elif command -v pacman &> /dev/null; then
if [ "$SKIP_DVD_TOOLS" = true ]; then
@ -208,7 +208,7 @@ else
if [ "$SKIP_DVD_TOOLS" = true ]; then
sudo zypper install -y ffmpeg
else
sudo zypper install -y ffmpeg dvdauthor genisoimage
sudo zypper install -y ffmpeg dvdauthor xorriso
fi
elif command -v brew &> /dev/null; then
if [ "$SKIP_DVD_TOOLS" = true ]; then