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"