JavaFX中不支持MP4吗?

所以我最近开始使用JavaFX尝试将video和音频插入到我的java程序中。 音频工作得很好,但出于某种原因,每次我尝试播放video文件时,都会返回MEDIA_UNSUPPORTEDexception。 我已经阅读并看到video文件需要是MP4(它是),所以我尝试将其转换为其他类型,然后使用几个不同的转换器将其重新转换为MP4(H.264和AAC)没有什么变化。

这是我正在使用的代码:

import java.net.URL; import javax.swing.JFrame; import javax.swing.SwingUtilities; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.embed.swing.JFXPanel; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.VBox; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import javafx.scene.media.MediaView; import javafx.util.Duration; public class CallVideo extends JFrame{ public static final String VID_URL = "file:/C:/Users/Public/Videos/Videos/testCon.mp4"; //http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4 private JFXPanel panel; public CallVideo(String url) { panel = new JFXPanel(); Platform.runLater(new Runnable() { public void run() { final Media clip = new Media(VID_URL); final MediaPlayer player = new MediaPlayer(clip); final MediaView viewer = new MediaView(player); viewer.setFitHeight(200); viewer.setFitWidth(200); final Button button = new Button("Bing Zzzzt!"); button.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { viewer.getMediaPlayer().seek(Duration.ZERO); viewer.getMediaPlayer().play(); } }); setMediaEventHandlers(viewer); VBox vid = new VBox(); vid.getChildren().addAll(viewer, button); Scene aScene = new Scene(vid, 200, 200); panel.setScene(aScene); } }); this.add(panel); this.setSize(500, 500); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } private void setMediaEventHandlers(final MediaView view) { final MediaPlayer player = view.getMediaPlayer(); System.out.println("Initial: " + player.getStatus()); player.statusProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) { System.out.println("Current: " + curStatus); } }); if (player.getError() != null) { System.out.println("Initial Error: " + player.getError()); } player.setOnError(new Runnable() { @Override public void run() { System.out.println("Current Error: " + player.getError()); } }); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new CallVideo(VID_URL); } }); } 

}

错误发生在初始化“Media”对象的行(构造函数的开头)。 我完全不知道问题是什么。 我已经看到有关音频播放的问题,但video没有出现,但它甚至没有为我这样做…

如果有人需要它:

日食

JDK 7

JavaFX 2.0

Windows 7专业版

编辑:

首先,我注意到我实际上正在使用JavaFX 2.0 ……这可能是问题所在吗?

我已经测试了答案中提供的两个版本,并且在使用该答案提供的URL时都返回此错误(由statusListener调用):

 Current Error: MediaException: MEDIA_UNSUPPORTED : com.sun.media.jfxmedia.MediaException: "Error enter code herelocator unsupported media format" : com.sun.media.jfxmedia.MediaException: "Error locator unsupported media format" 

使用我自己的文件时,程序在调用Media构造函数时立即返回此错误,如前所述:

 Exception in thread "AWT-EventQueue-0" MediaException: MEDIA_UNSUPPORTED : Unrecognized file signature! at javafx.scene.media.Media.(Media.java:382) at CallVideo.(CallVideo.java:27) at CallVideo$5.run(CallVideo.java:90) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$000(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) 

我已经更新了上面使用的代码。

解决了! 原因是我使用了一个不合适的JavaFX(可能还有JDK)。 我不是真的控制那些东西,因为这些都是学校的电脑,但这让我感觉不错……谢谢你的帮助! 我用最终代码更新了它。

在我修改你的程序以解决一些问题后,这对我有用。

swingvideoplayer

我申请的一些更改:

  1. 需要MediaView才能查看video,因此需要创建一个video并将其添加到活动的JavaFX场景中以便观看video。
  2. 需要在JavaFX应用程序线程而不是主线程上创建一些JavaFX控件,否则会得到java.lang.IllegalStateException: Toolkit not initialized
  3. 监视介质错误事件并添加一些诊断日志有助于解决介质编码问题。

仅限JavaFX的解决方案

您的程序将JavaFX嵌入到Swing应用程序中,该应用程序比在标准JavaFX应用程序中播放Media更复杂一些。 在我的回答中提供了在标准JavaFX应用程序中播放mp4的相应代码: 无法播放mp4转换文件 – JavaFX 2.1 。 除非您特别需要Swing(例如在现有的大型Swing应用程序中嵌入基于JavaFX的媒体播放器),否则建议仅使用JavaFX。

Oracle提供了一个很好的教程,用于将媒体资产合并到JavaFX应用程序中 。


JavaFX媒体包描述记录了JavaFX支持的媒体回放编码,容器和协议。


使用JavaFX MediaPlayer从Swing App播放mp4video的示例

请注意,该示例仅捕获可能的介质错误的子集。 对于可以捕获并记录所有介质错误的代码模板,请参阅JavaFX介质error handling文档 。

 import javax.swing.*; import javafx.application.Platform; import javafx.beans.value.*; import javafx.embed.swing.JFXPanel; import javafx.event.*; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.VBox; import javafx.scene.media.*; import javafx.util.Duration; public class VideoPlayer extends JFrame { public static final String VID_URL = "http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4"; private static final int VID_WIDTH = 320; private static final int VID_HEIGHT = 180; private static final int PLAYER_WIDTH = 320; private static final int PLAYER_HEIGHT = 265; private void play(final String url) { final JFXPanel panel = new JFXPanel(); Platform.runLater(new Runnable() { @Override public void run() { initFX(panel, url); } }); this.add(panel); this.setSize(PLAYER_WIDTH, PLAYER_HEIGHT); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } private void initFX(JFXPanel panel, String url) { MediaView mediaView = createMediaView(url); final Scene playerScene = new Scene( createPlayerLayout(mediaView), PLAYER_WIDTH, PLAYER_HEIGHT ); setMediaEventHandlers( mediaView ); panel.setScene(playerScene); } private MediaView createMediaView(String url) { final Media clip = new Media(url); final MediaPlayer player = new MediaPlayer(clip); final MediaView view = new MediaView(player); view.setFitWidth(VID_WIDTH); view.setFitHeight(VID_HEIGHT); return view; } private VBox createPlayerLayout(final MediaView view) { final Button button = new Button("Play From Start"); button.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { view.getMediaPlayer().seek(Duration.ZERO); view.getMediaPlayer().play(); } }); final VBox layout = new VBox(8); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll( view, button ); layout.setStyle("-fx-background-color: linear-gradient(to bottom, derive(lightseagreen, -20%), lightseagreen);"); return layout; } private void setMediaEventHandlers(final MediaView view) { final MediaPlayer player = view.getMediaPlayer(); System.out.println("Initial: " + player.getStatus()); player.statusProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) { System.out.println("Current: " + curStatus); } }); if (player.getError() != null) { System.out.println("Initial Error: " + player.getError()); } player.setOnError(new Runnable() { @Override public void run() { System.out.println("Current Error: " + player.getError()); } }); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { VideoPlayer player = new VideoPlayer(); player.play(VID_URL); } }); } } 

解决了!

很高兴看到原始海报能够使video播放工作,最后的错误只是使用了不支持mp4播放的旧JavaFX版本(2.0)。 更新到JavaFX 2.2+(支持mp4播放)修复了这个问题。