MediaPlayer(FX) вне JavaFX приложения

107
04 марта 2021, 00:40

Для того, чтобы пользоваться MediaPlayer, нужно использовать его в JavaFX потоке. Самая простая программа для запуска JavaFX приложения выглядит примерно так:

public final class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

Проблема в том, что я хочу с помощью этого MediaPlayer сделать "радио" с помощью мода в Minecraft (Forge 1.7.10) и как уже многие догадались, там нифига не JavaFX поток. Вопрос, есть ли способ использовать этот MediaPlayer вне JavaFX потока либо как нибудь имитировать его?

Я пробовал так, клиент запустился, по нажатию кнопки NumPad5 музыка играет но в логе запуска я вижу следующее:

[13:40:53] [Client thread/WARN] [FML]: =============================================================
[13:40:53] [Client thread/WARN] [FML]: MOD HAS DIRECT REFERENCE System.exit() THIS IS NOT ALLOWED REROUTING TO FML!
[13:40:53] [Client thread/WARN] [FML]: Offendor: com/sun/javafx/application/LauncherImpl.abort(Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
[13:40:53] [Client thread/WARN] [FML]: Use FMLCommonHandler.exitJava instead
[13:40:53] [Client thread/WARN] [FML]: =============================================================
[13:40:55] [JavaFX Application Thread/INFO] [radio]: JavaFX Application Thread
[13:40:56] [JavaFX Application Thread/INFO] [radio]: onReady

Это говорит о том, что система JavaFX хотела завершить работу приложения, ибо ей что-то не понравилось, но система Forge просто предотвратила этого.

UPD: оказалось что если фордж видит в коде System.exit() кидает варн такой. Хотя, по сути, метод может вообще никогда не вызываться.

@Mod(modid = Radio.MOD_ID, name = Radio.MOD_NAME, version = Radio.MOD_VERSION)
public class Radio {
    public static final String
            MOD_ID = "radio",
            MOD_NAME = "Radio",
            MOD_VERSION = "1.0";
    private final static KeyBinding playButton = new KeyBinding("key.playButton", Keyboard.KEY_NUMPAD5, "key.categories.radio");
    private final static KeyBinding stopButton = new KeyBinding("key.stopButton", Keyboard.KEY_NUMPAD4, "key.categories.radio");
    private MediaPlayerFX player;
    private static Logger logger;
    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        logger = event.getModLog();
        if (event.getSide().isClient()) {
            ClientRegistry.registerKeyBinding(playButton);
            ClientRegistry.registerKeyBinding(stopButton);
            FMLCommonHandler.instance().bus().register(this);
            //Application.launch(MediaPlayerFX.class) - если сделать так, но инициализация клиента зависает на этом.
            Thread thread = new Thread(() -> Application.launch(MediaPlayerFX.class));
            thread.setName("Run JavaFX Application Thread");
            thread.start();
        }
    }
    @SubscribeEvent
    @SideOnly(Side.CLIENT)
    public void key(InputEvent.KeyInputEvent event) {
        if (playButton.isPressed()) {
            MediaPlayerFX.instance.play();
        }
        if (stopButton.isPressed()) {
            MediaPlayerFX.instance.stopped();
        }
    }
    public static class MediaPlayerFX extends Application {
        private static MediaPlayerFX instance;
        private MediaPlayer player;
        public MediaPlayerFX() {
            instance = this;
        }
        @Override
        public void start(Stage stage) throws Exception {
            logger.info(Thread.currentThread().getName());
            this.player = new MediaPlayer(new Media("http://eptop128server.streamr.ru:8033/eptop128"));
            this.player.setOnReady(() -> {
                logger.info("onReady");
            });
            this.player.setOnError(() -> {
                logger.info("onError");
            });
            this.player.setOnStopped(() -> {
                logger.info("onStopped");
            });
            this.player.setOnEndOfMedia(() -> {
                logger.info("onEndOfMedia");
                this.player.stop();
            });
            this.player.setOnPaused(() -> {
                logger.info("onPause");
            });
        }
        private void play() {
            Platform.runLater(() -> this.player.play());
        }
        private void stopped() {
            Platform.runLater(() -> this.player.stop());
        }
    }
}

Может я поспешил с выбором библиотеки JavaFX для подобного? У кого-нибудь есть получше предложения что можно использовать?

READ ALSO
Почему int [] компилируется в Object []?

Почему int [] компилируется в Object []?

Почему при компиляции в Java - массив int преобразуется в массив Object? Ведь int это примитивный типКаким образом оно все становится объектом и главное...

107
Расположение элементов на экране

Расположение элементов на экране

Есть у нас приложение на андроид, у которого на фоне стоит картинка в PNG формате на которой в центре расположены 3 квадратаМне нужно создать...

112
Второй xml не создается

Второй xml не создается

Для общения с серваком, нужно отправлять ему несколько xml - так прописано в документации, и вот тут возникли сложности, так как второй xml не создается

89
Database Change Notification

Database Change Notification

Разбираюсь с механизмом нотификаций в ораклеВозникло два вопроса

120