当前位置: 首页 > 知识库问答 >
问题:

在javafx上使用媒体播放器时出现Java FX空指针异常。场景媒体MediaPlayer。初始化

缑勇锐
2023-03-14

媒体块中没有启动MediaPlayer的空字段

我对此进行了广泛的研究,但没有发现任何东西可以解释这个错误。

我正在为一个类项目构建一个Java Swing应用程序,并试图使用JFX面板和媒体播放器来主持和播放几个mp4视频。我已经成功地让它工作了一次,但是当我再次回到窗口时,我遇到了错误。

JAVAcom上的lang.NullPointerException。太阳媒体jfxmediaimpl。站台gstreamer。GSTMediaPlayer。playerSetBalance(来源不详)网站。太阳媒体jfxmediaimpl。NativeMediaPlayer。javafx上的setBalance(未知来源)。场景媒体MediaPlayer。javafx上的init(未知源代码)。场景媒体MediaPlayer。(未知来源)在项目中。屏幕。教程图层屏幕。project上的initMediaPlayer(tutorialPlayersScreen.java:156)。屏幕。教程图层屏幕。init(TutorialPlayerScreen.java:122)在project上。屏幕。教程图层屏幕。(TutorialPlayerScreen.java:113)在project上。按钮。PreKModuleSelectTutorialButtons$Button$7。项目中的doAction(PreKModuleSelectTutorialButtons.java:225)。屏幕。PreKModuleSelect。在project上单击(PreKModuleSelect.java:359)。工具。ContentPane。项目中的notifiyObserver(ContentPane.java:457)。工具。ContentPane 1美元。在java上按下鼠标(ContentPane.java:272)。awt。组成部分javax上的processMouseEvent(未知源代码)。摆动JComponent。java上的ProcessMouseeEvent(未知源代码)。awt。组成部分java上的processEvent(未知源)。awt。容器java上的processEvent(未知源)。awt。组成部分java上的dispatchEventImpl(未知源代码)。awt。容器java上的dispatchEventImpl(未知源代码)。awt。组成部分java上的dispatchEvent(未知源)。awt。轻量级调度员。java上的retargetMouseEvent(未知源代码)。awt。轻量级调度员。java上的ProcessMouseeEvent(未知源代码)。awt。轻量级调度员。java上的dispatchEvent(未知源)。awt。容器java上的dispatchEventImpl(未知源代码)。awt。窗java上的dispatchEventImpl(未知源代码)。awt。组成部分java上的dispatchEvent(未知源)。awt。事件队列。java上的dispatchEventImpl(未知源代码)。awt。事件队列。在java上访问500美元(未知来源)。awt。事件队列3美元。在java上运行(未知源代码)。awt。事件队列3美元。在java上运行(未知源代码)。安全访问控制器。java上的doPrivileged(本机方法)。安全ProtectionDomain 1美元。java上的doIntersectionPrivilege(未知源代码)。安全ProtectionDomain 1美元。java上的doIntersectionPrivilege(未知源代码)。awt。事件队列4美元。在java上运行(未知源代码)。awt。事件队列4美元。在java上运行(未知源代码)。安全访问控制器。java上的doPrivileged(本机方法)。安全ProtectionDomain 1美元。java上的doIntersectionPrivilege(未知源代码)。awt。事件队列。java上的dispatchEvent(未知源)。awt。EventDispatchThread。java上的pumpOneEventForFilters(未知源代码)。awt。EventDispatchThread。java上的pumpEventsForFilter(未知源代码)。awt。EventDispatchThread。java上的pumpEventsForHierarchy(未知源代码)。awt。EventDispatchThread。java上的pumpEvents(未知源)。awt。EventDispatchThread。java上的pumpEvents(未知源)。awt。EventDispatchThread。运行(未知源)

以下是我用来启动JFX媒体的代码:

'//媒体播放器支持私有组mediaRoot;私有场景mediaScene;

private Media tutorialVideo;
private MediaPlayer VideoPlayer;
private MediaView mediaViewer;
private JFXPanel fxPanel;

private int jfxPanelHeight = 394;//525;
private int jfxPanelWidth = 700;//700;

private void initMediaPlayer() throws IOException {
    this.fxPanel = new JFXPanel(); //initializes JFX variables
    fxPanel.setSize(this.jfxPanelWidth ,this.jfxPanelHeight);

    //Add JFX Panel component to the Main Window
    int padding = ((mainWindow.getPreferredSize().width - this.jfxPanelWidth) / 2);
    mainWindow.addLayer(fxPanel, MEDIA_LAYER, padding, 125);

    //Initialize FX Panel
    this.mediaRoot = new Group();
    this.mediaScene = new Scene(this.mediaRoot, 0, 0);

    //Open/prepare the file
    //String tutorialFilePath = new File("").getAbsolutePath() + DIRECTORY_PATH + "Tutorial.mp4";
    String tutorialFilePath = new File("").getAbsolutePath() + MEDIA_PATH + this.observer.getName() +"Tutorial.mp4";
    File mediaFile = new File(tutorialFilePath);
    this.tutorialVideo = new Media(mediaFile.toURI().toString());

    //Create the media player
    this.VideoPlayer = new MediaPlayer(this.tutorialVideo);  //Error here
    this.VideoPlayer.setAutoPlay(false);

    this.mediaViewer = new MediaView(this.VideoPlayer);
    this.mediaViewer.setFitHeight(this.jfxPanelHeight);
    this.mediaViewer.setFitWidth(this.jfxPanelWidth);
          ((Group)this.mediaScene.getRoot()).getChildren().add(this.mediaViewer);

    fxPanel.setScene(this.mediaScene);
}'

我试图在离开屏幕之前清理使用过的内存。

public void tearDown(){

    //Stop the JFX Player and Remove
    this.mainWindow.removeLayer(this.fxPanel);
    this.VideoPlayer.stop();
    this.VideoPlayer.dispose();
    this.fxPanel.removeAll();
    this.mediaRoot.getChildren().removeAll();

    this.mediaRoot = null;
    this.mediaScene = null;
    this.mediaViewer = null;
    this.tutorialVideo  = null;
    this.VideoPlayer = null;
    this.fxPanel = null;
}

private JLayeredPane contentPane;    //The content pane of this JFrame.
public void removeLayer(JComponent component) {
    contentPane.remove(component);
    contentPane.revalidate();
    contentPane.repaint();
}

任何帮助或评论都将不胜感激!谢谢!

共有2个答案

巫马欣嘉
2023-03-14

这可能不是导致NullPointerException的问题,但您需要在不同的线程上进行不同的方法调用。特别是,必须在AWT事件调度线程上调用new JFXPanel(),而initMediaPlayer的其余部分需要在FX Application Thread上调用。请参阅JFXPanel javadocs。(虽然这可能不是问题的原因,但可以想象它是。)-James_D

这就解决了问题。

我将JFX面板设置为由主窗口管理,并且从不超出范围。为了解决只在我想要的屏幕上显示的问题,我将函数改为。。。

public void tearDown(){
    this.mediaPanel.getMediaPanel().setVisible(false);
    this.VideoPlayer.stop();
}

private void initMediaPlayer() throws IOException {
    this.mediaPanel.getMediaPanel().setVisible(true);

    //Initialize FX Panel
    this.mediaRoot = new Group();
    this.mediaScene = new Scene(this.mediaRoot, 0, 0);

    //Open/prepare the file
    //String tutorialFilePath = new File("").getAbsolutePath() + DIRECTORY_PATH + "Tutorial.mp4";
    String tutorialFilePath = new File("").getAbsolutePath() + MEDIA_PATH + this.observer.getName() +"Tutorial.mp4";
    File mediaFile = new File(tutorialFilePath);
    this.tutorialVideo = new Media(mediaFile.toURI().toString());

    //Create the media player
    this.VideoPlayer = new MediaPlayer(this.tutorialVideo);  //Error here
    this.VideoPlayer.setAutoPlay(false);

    this.mediaViewer = new MediaView(this.VideoPlayer);
    this.mediaViewer.setFitHeight(this.mediaPanel.getPanelHeight());
    this.mediaViewer.setFitWidth(this.mediaPanel.getPanelWidth());
        ((Group)this.mediaScene.getRoot()).getChildren().add(this.mediaViewer);

    this.mediaPanel.getMediaPanel().setScene(this.mediaScene);
}

感谢所有帮助过我的人!

哈栋
2023-03-14

代码中存在线程问题,需要修复。具体来说,必须创建FX UI组件,并在FX应用程序线程上设置场景图。有关详细信息,请参阅Javadocs forJFXPanel

这是附带的空指针异常,然而.我认为是什么导致的是,当您从UI中完全删除JFXPanel时,FX工具包正在关闭.为了防止这种情况,只需调用

Platform.setImplicitExit(false);

当您第一次初始化应用程序时。(从任何线程调用此方法都是安全的。)

下面是一个类似的SSCCE:

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class MediaPlayerInSwing {

    private static final String MEDIA_URL = "http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv" ;

    private JFrame window ;

    private JFXPanel jfxPanel ;
    private Media media ;
    private MediaPlayer player ;
    private MediaView mediaView ;
    private BorderPane root ;
    private Scene scene ;

    private Button button ;

    // create on AWT Event Dispatch Thread
    public MediaPlayerInSwing() {
        Platform.setImplicitExit(false);
        initGUI();
    }

    private void initGUI()  {
        window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLayout(new BorderLayout());

        JPanel controls = new JPanel();
        controls.setLayout(new FlowLayout());
        button = new Button("Show video");
        controls.add(button);
        button.addActionListener(e -> {
            if (jfxPanel == null) {
                showVideo();
            } else {
                tearDownVideo();
            }
        });

        window.add(controls, BorderLayout.SOUTH);
        window.setSize(600, 480);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
    }

    private void showVideo() {


        jfxPanel = new JFXPanel();

        Platform.runLater(() -> {
            media = new Media(MEDIA_URL);
            player = new MediaPlayer(media);
            player.play(); 
            mediaView = new MediaView(player);
            root = new BorderPane(mediaView);
            scene = new Scene(root, 600, 400);
            jfxPanel.setScene(scene);
        });

        window.add(jfxPanel, BorderLayout.CENTER);
        button.setLabel("Hide video");
    }

    private void tearDownVideo() {

        window.remove(jfxPanel);

        Platform.runLater(() -> {
            player.stop();
            player.dispose();
            player = null ;
            mediaView = null ;
            root = null ;
            jfxPanel.setScene(null);
            scene = null ;
            SwingUtilities.invokeLater(() -> {
                jfxPanel = null ;
                // force window to repaint...
                window.getRootPane().repaint();
            });
        });
        button.setLabel("Show video");
    }

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(MediaPlayerInSwing::new);
    }
}
 类似资料:
  • 这可能不是一个可以接受的问题,但我现在非常绝望。 我需要一个同步java媒体播放器与快速寻找和平衡修改。 脚本: 我有一个javaFX项目,我必须在循环中播放一个非常短(50-100毫秒)的媒体文件。问题是,在重新启动之前,我需要等待一些要求。 简而言之:播放声音- javafx提供了一个我修改过的媒体播放器。 如果有人能为我指出正确的方向(图书馆/我错过的东西),我将不胜感激 ps允许的java

  • 我目前在一个项目中使用Javafx 2,我可能需要长时间无限循环播放一个视频。在windows上,当视频播放时,我的proifiler工具显示非常正常的图片,cpu负载不是很重(在2个内核上运行时约为2x40-50%),内存使用峰值约为250 MB,这是正常的。但是,当我在Ubuntu机器上部署应用程序时,每个内核的cpu负载达到70%左右(尽管它是一个双核atom处理器,所以假设这是正常的),内

  • 我对JavaFXMediaPlayer有问题。出于测试目的,我从http://docs.oracle.com/javafx/2/media/playercontrol.htm并添加了一些错误处理。使用以下错误处理时 我得到这个控制台输出: 视频采用h264和aac(音频)编码,分辨率为1920x1168px。分辨率大于1920x1080px的每个视频都会出现此错误。分辨率为1920x1080px或

  • 最初,我试图从javafx项目中创建跨平台的可执行文件。一切正常,所以我想在我的项目中添加音频,所以我在在我添加javafx媒体依赖性之前,一切都很好,但现在我得到了一个错误,也不能解析媒体类。如何解决这个问题? 仅供参考,我正在使用: 项目:Maven Java:JDK 13 IDE:netbean 13 Javafx:openjfx 11 下面是我的项目结构: 如果你需要更多的澄清,请告诉我。

  • 我目前正在使用MediaPlayer播放来自web的实时流。问题是MediaPlayer缓冲区很大,它坚持在播放前缓冲10秒左右。Android-ICS 4.0中的MediaPlayer缓冲区大小 所以我的问题是,有没有另外一种不用MediaPlayer播放媒体流(mp3)的方法?也许使用InputStream或甚至第三方媒体播放器不会有相同的缓冲问题?

  • 媒体播放器类很好。然而,我无法播放存储在另一个类中的mp3文件(当鼠标单击时)。有人能检查我的密码吗? 这是我尝试用来播放音频文件的类: 当我运行程序时(在下面勾选的鼠标上),我得到了以下两个错误:错误1:线程“AWT-EventQueue-0”java.lang中的异常。不支持的操作异常:尚未实现错误2:线程“thread-3”java.llang中的例外。IllegalStateExcepti