【问题标题】:JavaFX video not playingJavaFX 视频不播放
【发布时间】:2013-12-15 18:19:40
【问题描述】:

我遵循了一些关于将 JavaFX 与 Swing (JFrame) 结合来播放视频的教程,但是我得到的只是一个黑屏,其中视频应该没有任何实际内容播放,也没有报告错误。

我在这里做错了什么,为什么视频无法播放?

我尝试了几个 .flv 视频,它们都不会开始播放(当我在浏览器中打开它们时它们会播放)

我在安装了 K-lite 完整编解码器包的 Windows 8.1 N Pro 上运行 jre7 和 jdk1.7.0_45

编辑:在jewelsea评论后更新了我的代码,没有任何改变,黑框仍然出现,没有内容播放,控制台没有显示任何文本

package com.example.test;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.media.Media;
import javafx.scene.media.MediaErrorEvent;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;

import javax.swing.*; 

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                initAndShowGUI();
            }
        });
    }

    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Test");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(640, 480);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
       });
    }

    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }

    private static Scene createScene() {
        String source;
        Media media;
        MediaPlayer mediaPlayer;
        MediaView mediaView = null;
        try {
            media = new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
            if (media.getError() == null) {
                media.setOnError(new Runnable() {
                    public void run() {
                        // Handle asynchronous error in Media object.
                        System.out.println("Handle asynchronous error in Media object");
                    }
                });
                try {
                    mediaPlayer = new MediaPlayer(media);
                    mediaPlayer.setAutoPlay(true);

                    if (mediaPlayer.getError() == null) {
                        mediaPlayer.setOnError(new Runnable() {
                            public void run() {
                                // Handle asynchronous error in MediaPlayer object.
                                System.out.println("Handle asynchronous error in MediaPlayer object");
                            }
                        });
                        mediaView = new MediaView(mediaPlayer);
                        mediaView.setOnError(new EventHandler() {
                            public void handle(MediaErrorEvent t) {
                                // Handle asynchronous error in MediaView.
                                System.out.println("Handle asynchronous error in MediaView: "+ t.getMediaError());
                            }

                            @Override
                            public void handle(Event arg0) {
                                // TODO Auto-generated method stub
                                System.out.println("Handle asynchronous error in MediaView arg0: "+arg0.toString());
                            }
                        });
                    } else {
                        // Handle synchronous error creating MediaPlayer.
                        System.out.println("Handle synchronous error creating MediaPlayer");
                    }
                } catch (Exception mediaPlayerException) {
                    // Handle exception in MediaPlayer constructor.
                    System.out.println("Handle exception in MediaPlayer constructor: "+ mediaPlayerException.getMessage());
                }
            } else {
                // Handle synchronous error creating Media.
                System.out.println("Handle synchronous error creating Media");
            }
        } catch (Exception mediaException) {
            // Handle exception in Media constructor.
            System.out.println("Handle exception in Media constructor: "+mediaException.getMessage());
        }

        Group  root  =  new  Group();
        Scene  scene  =  SceneBuilder.create().width(640).height(480).root(root).fill(Color.WHITE).build();

        if(mediaView != null) {
            root.getChildren().add(mediaView);
        }

        return scene;
    }
}

【问题讨论】:

  • 在 JavaFX 中捕获媒体错误是很挑剔的。 JavaFX 媒体 javadoc 中有一个 error catching template。在您的程序中实施模板并使用您的结果更新问题。还要检查您的非 oracle flv 文件是否经过 vp6 编码。
  • 我添加了模板,不幸的是没有抛出异常
  • 您是否尝试在纯 FX 应用程序中播放该视频?
  • 我不记得了,您有什么建议(或演示)可以尝试吗?我不确定这是否会有所帮助,因为我的代码对其他人来说似乎运行良好,而对我来说却不是

标签: java swing javafx


【解决方案1】:

所以我安装了 windows 媒体功能包以使 adobe Premiere pro 正常工作(因为它需要来自 windows 媒体播放器的 dll 文件(我没有安装它,因为我运行的是 N 版本的 windows),现在视频确实为我播放。

我不能 100% 确认原因是没有安装 WMP,因为媒体功能包可能还安装了其他解决我问题的东西,但是,问题解决了 :)

我要感谢其他答案的尝试,我真的很感激。

【讨论】:

【解决方案2】:

如果我正在写这个答案,请不要介意。我知道这是一个非常古老的问题,但这个答案可能对其他人有所帮助。我目前正在开发一个需要根据文件类型执行文件的 JavaFX 应用程序。 我的应用程序第一次播放了该视频,但是当我单击另一个 mp4 视频文件时它没有播放。 这是我的初始代码。

private void playVideo(String fileLocation) {
        System.out.println("VideoProcesser Thread = " + Thread.currentThread().getName());
        media = new Media(new File(fileLocation).toURI().toString());
        mediaPlayer = new MediaPlayer(media);
        mediaView = new MediaView(mediaPlayer);
        runnable = () -> {
            System.out.println("Inside runnable VideoProcesser Thread = " + Thread.currentThread().getName());
            mediaPlayer.play();
        };
        mediaPlayer.setOnReady(runnable);
        setVideoMediaStatus(PLAYING);
        pane.getChildren().add(mediaView);
    }

然后由于视频播放器屏幕很暗,我认为问题出在媒体视图上,所以我添加了以下两行,

 if(mediaView == null) {
            mediaView = new MediaView(mediaPlayer);
        }
        mediaView.setMediaPlayer(mediaPlayer);

现在,当我点击不同的视频时,我的应用程序可以正常播放。 这是完整的代码。

Media media;
MediaPlayer mediaPlayer;
MediaView mediaView;   

private void playVideo(String fileLocation) {
            System.out.println("VideoProcesser Thread = " + Thread.currentThread().getName());
            media = new Media(new File(fileLocation).toURI().toString());
            mediaPlayer = new MediaPlayer(media);
            mediaPlayer.setAutoPlay(true);
            if(mediaView == null) {
                mediaView = new MediaView(mediaPlayer);
            }
            mediaView.setMediaPlayer(mediaPlayer);
            mediaPlayer.play();
            mediaPlayer.setOnError(() -> System.out.println("Current error: "+mediaPlayer.getError()));
            setVideoMediaStatus(PLAYING);
            pane.getChildren().add(mediaView);
        }

请注意,如果您使用 FXML 实例化 mediaView,则不要再次实例化它。再次实例化它可能会使 mediaView 失去原始节点的引用。 参考itachi的这篇帖子和回答, javafx mediaview only the audio is playing

【讨论】:

    【解决方案3】:

    试试这个,它对我有用:

    package de.professional_webworkx.swing;
    
    import javafx.application.Platform;
    import javafx.embed.swing.JFXPanel;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.SceneBuilder;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.media.MediaView;
    
    import javax.swing.JFrame;
    
    public class MyFrame extends JFrame {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        /**
         * Create a new Frame, set title, ...
         */
        public MyFrame() {
    
            this.setTitle("Swing and JavaFX");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setSize(1024, 768);
    
            // create a JFXPanel
            final JFXPanel jfxPanel = new JFXPanel();
    
            // add the jfxPanel to the contentPane of the JFrame
            this.getContentPane().add(jfxPanel);
            this.setVisible(true);
    
            Platform.runLater(new Runnable() {
    
                @Override
                public void run() {
                    jfxPanel.setScene(initScene());
                }
            });
        }
    
        public static final void main (String[] args) {
            new MyFrame();
        }
    
        /**
         * init the JFX Scene and 
         * @return scene
         */
        private Scene initScene() {
    
            Group root = new Group();
            SceneBuilder<?> sb = SceneBuilder.create().width(640).height(400).root(root);
            Media video = new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
            MediaPlayer mediaPlayer = new MediaPlayer(video);
            mediaPlayer.setAutoPlay(true);
            mediaPlayer.play();
    
            MediaView view = new MediaView(mediaPlayer);
    
            root.getChildren().add(view);
            Scene scene = sb.build();
    
    
            return scene;
    
        }
    }
    

    帕特里克

    【讨论】:

    • 不幸的是,这也只是在窗口中给出了一个黑框,看起来好像视频不会加载但没有返回异常等
    • 您使用 JDK >= 1.7 Update 10 并手动将 jfxrt.jar 添加到您的 Classpath 中?
    • 从oracle加载flv只需要0.5s,然后视频开始播放。
    • 不适合我,让程序运行了几分钟但什么也没发生
    • 我也不认为问题出在视频本身,我有几个本地 flv 文件也无法播放,但由于应用程序没有抛出任何异常并且 eclipse 没有报告任何错误我不知道可能是什么原因。
    【解决方案4】:

    我获取了您的代码并尝试在我的机器(Win7 JDK 1.7.0_25)上运行它并得到了相同的结果。黑匣子,没有视频。

    我注意到你没有设置mediaPlayer.setAutoPlay(true),所以我在mediaPlayer 传递给MediaView 之前添加了对createScene() 的调用。现在播放似乎对我有用。

    // ... prior code omitted
    
        // added this to OP's code
        mediaPlayer.setAutoPlay(true);
    
        mediaView = new MediaView(mediaPlayer);
        mediaView.setOnError(new EventHandler() {
            public void handle(MediaErrorEvent t) {
                // Handle asynchronous error in MediaView.
                System.out.println("Handle asynchronous error in MediaView: "+ t.getMediaError());
            }
    
    // ... additional code omitted
    

    编辑: autoPlay 属性默认为 false - 您可以调用 mediaPlayer.isAutoPlay() 来检查这一点。如果不调用mediaPlayer.setAutoPlay(true)mediaPlayer.play(),视频将永远不会开始播放。

    编辑 2: 我刚刚在另一个答案的 cmets 中注意到,您在 JavaFX 之外播放视频时遇到问题。如果您还没有安装它,请尝试下载VLC 以查看视频是否可以使用它播放。我相信安装ffdshow tryouts 将提供必要的编解码器以在 Windows Media Player 中播放 FLV。 (虽然我认为所有版本的 K-lite 编解码器包都包含 FLV 支持)

    【讨论】:

    • 我添加了自动播放(一定是滑到了某个地方,我原来确实有)并安装了 ffdshow 试用版(我已经安装了 VLC)不幸的是仍然没有播放
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多