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>
67 lines
1.7 KiB
Java
67 lines
1.7 KiB
Java
package org.homebrew;
|
|
|
|
import java.awt.BorderLayout;
|
|
import javax.tv.xlet.Xlet;
|
|
import javax.tv.xlet.XletContext;
|
|
import javax.tv.xlet.XletStateChangeException;
|
|
import org.havi.ui.HScene;
|
|
import org.havi.ui.HSceneFactory;
|
|
|
|
public class MyXlet extends Thread implements Xlet {
|
|
private HScene scene;
|
|
private AdjustmentsMenu menu;
|
|
private boolean running;
|
|
|
|
public void initXlet(XletContext context) throws XletStateChangeException {
|
|
menu = new AdjustmentsMenu();
|
|
menu.setSize(1280, 720);
|
|
|
|
scene = HSceneFactory.getInstance().getDefaultHScene();
|
|
scene.add(menu, BorderLayout.CENTER);
|
|
scene.addKeyListener(menu);
|
|
scene.validate();
|
|
scene.repaint();
|
|
}
|
|
|
|
public void startXlet() throws XletStateChangeException {
|
|
running = true;
|
|
menu.setVisible(true);
|
|
scene.setVisible(true);
|
|
menu.requestFocus();
|
|
scene.requestFocus();
|
|
// Start the feature immediately so VLC always has a live playlist behind
|
|
// the menu (avoids the background->playlist transition it botches).
|
|
menu.startPlayback();
|
|
start();
|
|
}
|
|
|
|
public void pauseXlet() {
|
|
if (menu != null) {
|
|
menu.setVisible(false);
|
|
}
|
|
}
|
|
|
|
public void destroyXlet(boolean unconditional) {
|
|
running = false;
|
|
interrupt();
|
|
|
|
if (scene != null && menu != null) {
|
|
menu.setVisible(false);
|
|
scene.remove(menu);
|
|
}
|
|
|
|
scene = null;
|
|
menu = null;
|
|
}
|
|
|
|
public void run() {
|
|
while (running) {
|
|
try {
|
|
Thread.sleep(1000);
|
|
} catch (InterruptedException e) {
|
|
running = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|