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:
parent
48c172cb80
commit
4c270b744f
10 changed files with 362 additions and 25 deletions
|
|
@ -7,8 +7,15 @@ import java.awt.FontMetrics;
|
|||
import java.awt.Graphics;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import javax.media.ControllerEvent;
|
||||
import javax.media.ControllerListener;
|
||||
import javax.media.EndOfMediaEvent;
|
||||
import javax.media.Manager;
|
||||
import javax.media.MediaLocator;
|
||||
import javax.media.Player;
|
||||
import javax.media.Time;
|
||||
|
||||
public class AdjustmentsMenu extends Container implements KeyListener {
|
||||
public class AdjustmentsMenu extends Container implements KeyListener, ControllerListener {
|
||||
private static final String[] MAIN_ITEMS = {
|
||||
"MAIN FEATURE",
|
||||
"BONUS: WAITING ROOM OUTTAKES",
|
||||
|
|
@ -30,6 +37,8 @@ public class AdjustmentsMenu extends Container implements KeyListener {
|
|||
private boolean hidden;
|
||||
private int codeProgress;
|
||||
private String status = "BD-J scaffold loaded";
|
||||
private Player featurePlayer;
|
||||
private boolean menuShown = true;
|
||||
|
||||
public AdjustmentsMenu() {
|
||||
setFocusable(true);
|
||||
|
|
@ -111,7 +120,11 @@ public class AdjustmentsMenu extends Container implements KeyListener {
|
|||
selected = 0;
|
||||
status = "Returned to approved materials";
|
||||
} else if ("MAIN FEATURE".equals(item)) {
|
||||
status = "Main feature is playlist 00000";
|
||||
// The feature is already playing behind the menu; just hide the
|
||||
// menu to reveal it. Press the menu key (or ENTER) to bring it back.
|
||||
status = "Playing main feature -- press ENTER for menu";
|
||||
setMenuVisible(false);
|
||||
return;
|
||||
} else if ("SETTINGS".equals(item)) {
|
||||
status = "Settings stub selected";
|
||||
} else {
|
||||
|
|
@ -121,6 +134,47 @@ public class AdjustmentsMenu extends Container implements KeyListener {
|
|||
repaint();
|
||||
}
|
||||
|
||||
// Called once by the Xlet at startup. Start the feature playing straight
|
||||
// away and leave it running for the whole session. This keeps VLC in normal
|
||||
// "playing" mode with a live playlist behind the menu, so selecting an item
|
||||
// never triggers the background->playlist transition that VLC botches
|
||||
// ("blurayReleaseVout: subpicture channel exists", no video). The menu is
|
||||
// just drawn on top and toggled with setMenuVisible().
|
||||
public void startPlayback() {
|
||||
if (featurePlayer != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// libbluray's "bd" protocol; PLAYLIST:00000 -> BDMV/PLAYLIST/00000.mpls.
|
||||
featurePlayer = Manager.createPlayer(new MediaLocator("bd://PLAYLIST:00000"));
|
||||
featurePlayer.addControllerListener(this);
|
||||
featurePlayer.start();
|
||||
} catch (Exception e) {
|
||||
featurePlayer = null;
|
||||
status = "Playback failed: " + e.getMessage();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
// Toggle only this menu Container, not the whole HScene, so the scene (and
|
||||
// its key listener) stays alive while the video shows underneath.
|
||||
private void setMenuVisible(boolean visible) {
|
||||
menuShown = visible;
|
||||
setVisible(visible);
|
||||
if (visible) {
|
||||
requestFocus();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void controllerUpdate(ControllerEvent event) {
|
||||
// Loop the feature so there is always a live playlist behind the menu.
|
||||
if (event instanceof EndOfMediaEvent && featurePlayer != null) {
|
||||
featurePlayer.setMediaTime(new Time(0));
|
||||
featurePlayer.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void unlockHidden() {
|
||||
hidden = true;
|
||||
selected = 0;
|
||||
|
|
@ -131,6 +185,14 @@ public class AdjustmentsMenu extends Container implements KeyListener {
|
|||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
int code = e.getKeyCode();
|
||||
|
||||
// When the menu is hidden (feature playing full screen), any key brings
|
||||
// the menu back over the still-running video.
|
||||
if (!menuShown) {
|
||||
setMenuVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] items = hidden ? HIDDEN_ITEMS : MAIN_ITEMS;
|
||||
|
||||
if (code == KeyEvent.VK_UP) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ public class MyXlet extends Thread implements Xlet {
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue