Play feature under the menu; add mpv path; simplify VLC launch

Root causes found this session (all player-side, disc is valid -- bd_info
validates it and mpv plays the ISO's feature directly):

- Plain 'vlc <iso>' can't run ANY BD-J: system Java is 26, and libbluray's BD-J
  needs a JVM where System.setSecurityManager() works (<=21). run-vlc.sh pins
  mise Temurin 8, which is why it gets a menu at all.
- The BD-J VFS-cache 'error creating /tmp/libbluray-bdj-cache' flood is
  libbluray's SecurityManager.canWrite() denying the cache root while an Xlet
  context is active. Fixed by pointing TMPDIR at LIBBLURAY_CACHE_ROOT (buda
  root), which canWrite() allows unconditionally.
- Menu->playback failed with 'blurayReleaseVout: subpicture channel exists':
  VLC botches the background->playlist transition for an idle BD-J menu. Now the
  Xlet starts the feature immediately and draws the menu on top, so VLC stays in
  normal playing mode; MAIN FEATURE just hides the menu, any key brings it back,
  and the feature loops.

Also: drop the redundant tools/vlc-plugins swap (system VLC already ships the
bluray plugin), and add scripts/run-mpv.sh to play the feature with no BD-J/JVM
at all. Vendored the SDK helloworld sample for reference.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
happy 2026-08-25 16:25:42 -04:00
parent 48c172cb80
commit 4c270b744f
10 changed files with 362 additions and 25 deletions

29
scripts/run-mpv.sh Normal file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
# Play the disc's feature straight from the ISO (or a BDMV folder) with mpv.
#
# mpv links libbluray and plays Blu-ray *titles/playlists* directly. It does NOT
# run BD-J -- there is no menu, no Xlet, no Java involved. This is purely "open
# the disc and watch the movie", and unlike the VLC/BD-J path it Just Works with
# no JVM or cache setup. Use scripts/run-vlc.sh if you want the BD-J menu.
#
# Pass a path to override the default (an .iso image or a BDMV folder).
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TARGET="${1:-$ROOT_DIR/build/adjustments.iso}"
if [[ ! -e "$TARGET" ]]; then
echo "Missing disc target: $TARGET" >&2
echo "Run: make" >&2
exit 1
fi
if [[ -d "$TARGET" ]]; then
DEVICE="$(cd "$TARGET" && pwd)"
else
DEVICE="$(cd "$(dirname "$TARGET")" && pwd)/$(basename "$TARGET")"
fi
# bd://longest plays the main title; --bluray-device points at the image/folder.
exec mpv --bluray-device="$DEVICE" "bd://longest"

View file

@ -4,15 +4,9 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MISE_BIN="${MISE_BIN:-$HOME/.local/bin/mise}"
# 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).
# Default to the on-disk BDMV folder; pass an explicit path to override (a
# folder or an .iso). The folder is just the simpler preview target -- a real
# player reads the JAR from the ISO's disc filesystem directly.
TARGET="${1:-$ROOT_DIR/build/disc}"
if [[ -d "$TARGET" && ! -d "$TARGET/BDMV" ]]; then
@ -43,14 +37,34 @@ if [[ -n "$JDK8_HOME" ]]; then
export LD_LIBRARY_PATH="$JDK8_HOME/jre/lib/amd64/server:${LD_LIBRARY_PATH:-}"
fi
LOCAL_VLC_PLUGINS="$ROOT_DIR/tools/vlc-plugins/usr/lib/vlc/plugins"
if [[ -d "$LOCAL_VLC_PLUGINS" ]]; then
export VLC_PLUGIN_PATH="$LOCAL_VLC_PLUGINS:/usr/lib/vlc/plugins${VLC_PLUGIN_PATH:+:$VLC_PLUGIN_PATH}"
fi
# Note: no VLC_PLUGIN_PATH juggling. This system's VLC already ships the bluray
# access plugin (/usr/lib/vlc/plugins/access/liblibbluray_plugin.so); the old
# tools/vlc-plugins copy was only needed for split-package installs that lack it.
# Give libbluray writable BD-J storage roots, and -- the important part -- put
# the BD-J VFS cache *under* the cache (BUDA) root.
#
# libbluray copies the disc's JAR and fonts into a VFS cache under java.io.tmpdir
# (default /tmp/libbluray-bdj-cache). Its BD-J SecurityManager.canWrite() checks
# roots in this order: budaRoot -> persistentRoot -> (if an Xlet context is
# active: DENY) -> cacheRoot. That extraction often runs while an Xlet context is
# live on the thread, so the write is denied before the cacheRoot allowance is
# ever reached -- the flaky "error creating .../libbluray-bdj-cache" /
# "failed to create temporary cache directory" cascade that stops the Xlet (menu)
# from loading. budaRoot/persistentRoot are allowed unconditionally, so pointing
# TMPDIR (== java.io.tmpdir == the VFS cache's base) at the buda root makes the
# cache path start with budaRoot and always pass the write check.
BDJ_RUN_DIR="$ROOT_DIR/build/bdj-runtime"
export LIBBLURAY_CACHE_ROOT="$BDJ_RUN_DIR/cache"
export LIBBLURAY_PERSISTENT_ROOT="$BDJ_RUN_DIR/persistent"
export TMPDIR="$LIBBLURAY_CACHE_ROOT"
mkdir -p "$LIBBLURAY_CACHE_ROOT" "$LIBBLURAY_PERSISTENT_ROOT"
# start each preview from a clean VFS cache
rm -rf "$LIBBLURAY_CACHE_ROOT/libbluray-bdj-cache"
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"
exec vlc --bluray-menu "bluray://$ABS_TARGET"