From 48c172cb80f4f657009fe10a43862cb3365fd8c3 Mon Sep 17 00:00:00 2001 From: happy Date: Tue, 25 Aug 2026 14:57:31 -0400 Subject: [PATCH] Preview from BDMV folder so the BD-J menu Xlet actually loads The disc structure, signed JAR, and video are all valid. The menu never appeared because 'make run' opened the UDF .iso: libbluray's BD-J stack must copy BDMV/JAR/00000.jar out of the image into /tmp/libbluray-bdj-cache before the JVM can load it, and that write is refused by libbluray's BD-J SecurityManager (usingUdf=true / no disc root). With no JAR mounted the Xlet class isn't found (ClassNotFoundException: org.homebrew.MyXlet) and VLC falls back to the raw playlist -> video, no menu. Opening the build/disc BDMV folder instead lets libbluray read the JAR directly, so the Xlet loads and the menu overlay runs. The ISO is still built for burning; real players read the JAR from the disc filesystem directly. - run-vlc.sh: default to build/disc, accept folder or .iso, add --bluray-menu - Makefile: 'run' depends on the disc folder, not the ISO - README: document the folder-vs-ISO libbluray caveat Co-Authored-By: Claude Opus 4.8 --- Makefile | 7 +++++-- README.md | 15 ++++++++++++--- scripts/run-vlc.sh | 30 +++++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index b0ce61b..eff377f 100644 --- a/Makefile +++ b/Makefile @@ -102,8 +102,11 @@ inspect: $(ISO_FILE) bd_info $(ISO_FILE) bd_list_titles $(ISO_FILE) -a -run: bootstrap $(ISO_FILE) - scripts/run-vlc.sh $(ISO_FILE) +# Preview the menu straight from the BDMV folder. libbluray loads the BD-J Xlet +# from a folder but not from a UDF .iso on this setup (see scripts/run-vlc.sh), +# so `run` intentionally does not depend on the ISO. +run: bootstrap $(JAR_FILE) + scripts/run-vlc.sh $(DISC_DIR) open: run diff --git a/README.md b/README.md index eecb3ed..f1c603f 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,22 @@ The ISO is written to: build/adjustments.iso ``` -`make run` launches VLC through the Blu-ray access module, not as a generic -media file: +`make run` previews the disc by pointing VLC's Blu-ray access module at the +`build/disc` BDMV **folder**, not the ISO: ```sh -vlc bluray:///absolute/path/to/build/adjustments.iso +vlc --bluray-menu bluray:///absolute/path/to/build/disc ``` +Why the folder and not the ISO: when libbluray opens a UDF `.iso`, its BD-J +runtime must copy `BDMV/JAR/00000.jar` out of the image into a temp cache dir +before the JVM can load it. On this setup that write is refused by libbluray's +BD-J `SecurityManager`, so the Xlet class is never found and VLC silently falls +back to playing the raw playlist with no menu. Reading the folder lets +libbluray load the JAR directly, so the menu Xlet runs. The ISO is still the +artifact you burn/distribute; real players read the JAR from the disc +filesystem directly and are unaffected. + The initial menu is a Java Xlet overlay with a few bonus-feature placeholders and a hidden menu stub. The actual generated video is a short ffmpeg SMPTE bars pattern with AC-3 audio, authored as playlist `00000`. diff --git a/scripts/run-vlc.sh b/scripts/run-vlc.sh index 085fb1b..e6f79e7 100755 --- a/scripts/run-vlc.sh +++ b/scripts/run-vlc.sh @@ -1,12 +1,28 @@ #!/usr/bin/env bash set -euo pipefail -ISO_PATH="${1:-build/adjustments.iso}" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" MISE_BIN="${MISE_BIN:-$HOME/.local/bin/mise}" -if [[ ! -f "$ISO_PATH" ]]; then - echo "Missing ISO: $ISO_PATH" >&2 +# Default to the on-disk BDMV folder, not the ISO. +# +# When libbluray opens a UDF *image* (.iso), its BD-J stack must first copy +# BDMV/JAR/00000.jar out of the image into a temp cache dir. On this setup that +# write is refused by libbluray's BD-J SecurityManager (usingUdf=true, no disc +# root), so the JAR never mounts, the Xlet class is never found, and VLC falls +# back to playing the raw playlist with no menu. Opening the *folder* lets +# libbluray read the JAR directly, so the Xlet (menu) loads. Pass an explicit +# path to override (folder or .iso). +TARGET="${1:-$ROOT_DIR/build/disc}" + +if [[ -d "$TARGET" && ! -d "$TARGET/BDMV" ]]; then + echo "Not a BDMV folder (no BDMV/ inside): $TARGET" >&2 + echo "Run: make" >&2 + exit 1 +fi + +if [[ ! -e "$TARGET" ]]; then + echo "Missing disc target: $TARGET" >&2 echo "Run: make" >&2 exit 1 fi @@ -32,5 +48,9 @@ if [[ -d "$LOCAL_VLC_PLUGINS" ]]; then export VLC_PLUGIN_PATH="$LOCAL_VLC_PLUGINS:/usr/lib/vlc/plugins${VLC_PLUGIN_PATH:+:$VLC_PLUGIN_PATH}" fi -ABS_ISO="$(cd "$(dirname "$ISO_PATH")" && pwd)/$(basename "$ISO_PATH")" -exec vlc --reset-plugins-cache "bluray://$ABS_ISO" +if [[ -d "$TARGET" ]]; then + ABS_TARGET="$(cd "$TARGET" && pwd)" +else + ABS_TARGET="$(cd "$(dirname "$TARGET")" && pwd)/$(basename "$TARGET")" +fi +exec vlc --reset-plugins-cache --bluray-menu "bluray://$ABS_TARGET"