使用JMF播放MPEG等格式视频抛出CannotRealizeException问题求助
问题描述
我正通过相关教程学习使用JMF播放视频,运行时抛出无法实现播放器的错误,选中官方支持格式的视频文件后提示Could not realize Media PLayer,试过mpg、mpeg、au等适配格式都无法正常播放,问题现象如下:
报错信息
Unable to handle format: MPEG, 1280x720, FrameRate=23.9, Length=1382400 Failed to realize: com.sun.media.PlaybackEngine@659a969b Error: Unable to realize com.sun.media.PlaybackEngine@659a969b javax.media.CannotRealizeException at javax.media.Manager.blockingCall(Manager.java:2005) at javax.media.Manager.createRealizedPlayer(Manager.java:528) at com.mycompany.mavenproject3.MediaPanel.<init>(MediaPanel.java:33) at com.mycompany.mavenproject3.MediaTest.main(MediaTest.java:47) Could not realize media player
相关代码
MediaPanel.java
import java.awt.BorderLayout; import java.awt.Component; import java.io.IOException; import java.net.URL; import javax.media.CannotRealizeException; import javax.media.Manager; import javax.media.NoPlayerException; import javax.media.Player; import javax.swing.JPanel; public class MediaPanel extends JPanel { public MediaPanel( URL mediaURL ) { setLayout( new BorderLayout() ); // use a BorderLayout // Use lightweight components for Swing compatibility Manager.setHint( Manager.LIGHTWEIGHT_RENDERER, true ); try { // create a player to play the media specified in the URL Player mediaPlayer = Manager.createRealizedPlayer( mediaURL ); // get the components for the video and the playback controls Component video = mediaPlayer.getVisualComponent(); Component controls = mediaPlayer.getControlPanelComponent(); if ( video != null ){ add( video, BorderLayout.CENTER ); } if ( controls != null ){ add( controls, BorderLayout.SOUTH ); } mediaPlayer.start(); // start playing the media clip } // end try catch ( NoPlayerException noPlayerException ) { System.err.println( "No media player found" ); } // end catch catch ( CannotRealizeException cannotRealizeException ) { System.err.println( "Could not realize media player" ); } // end catch catch ( IOException iOException ) { System.err.println( "Error reading from the source" ); } // end catch } // end MediaPanel constructor } // end class MediaPanel
MediaTest.java
import java.io.File; import java.net.MalformedURLException; import java.net.URL; import javax.swing.JFileChooser; import javax.swing.JFrame; public class MediaTest{ public static void main( String args[] ) { JFileChooser fileChooser = new JFileChooser(); int result = fileChooser.showOpenDialog( null ); if ( result == JFileChooser.APPROVE_OPTION ) // user chose a file { URL mediaURL = null; try { mediaURL = fileChooser.getSelectedFile().toURL(); } catch ( MalformedURLException malformedURLException ) { System.err.println( "Could not create URL for the file" ); } if ( mediaURL != null ) { JFrame mediaTest = new JFrame( "Media Tester" ); mediaTest.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); MediaPanel mediaPanel = new MediaPanel( mediaURL ); mediaTest.add( mediaPanel ); mediaTest.setSize( 300, 300 ); mediaTest.setVisible( true ); } } } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany</groupId> <artifactId>mavenproject3</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>javax.media</groupId> <artifactId>jmf</artifactId> <version>2.1.1e</version> </dependency> <dependency> <groupId>com.conviva.sdk</groupId> <artifactId>conviva-mediaplayer-sdk</artifactId> <version>2.145.0</version> <type>aar</type> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>16</maven.compiler.source> <maven.compiler.target>16</maven.compiler.target> </properties> </project>
解决方案
- 替换JMF依赖包:公共maven仓库中的jmf 2.1.1e是精简版,缺少原生解码组件和格式支持库,需要获取完整的JMF安装包,提取
jmf.jar、sound.jar、mediaplayer.jar三个核心包,手动导入到本地maven仓库替换现有依赖。 - 切换兼容JDK版本:JMF最后更新为2004年,仅支持JDK1.4到JDK8版本,你当前使用的JDK16无法兼容,将pom中的
maven.compiler.source和maven.compiler.target修改为1.8,本地运行环境同步切换为JDK8。 - 调整视频参数:JMF支持的MPEG1/2视频分辨率最高为720x480,最高帧率30fps,你使用的1280x720规格超出支持范围,将测试视频转码为低分辨率MPEG1格式后再测试。
- 修改Player初始化逻辑:不要直接调用
createRealizedPlayer同步初始化,改为分步异步加载避免资源锁问题,修改后的核心代码如下:
import javax.media.ControllerEvent; import javax.media.ControllerListener; import javax.media.PrefetchCompleteEvent; import javax.media.RealizeCompleteEvent; // 替换原有Player初始化逻辑 Player mediaPlayer = Manager.createPlayer(mediaURL); mediaPlayer.addControllerListener(new ControllerListener() { @Override public void controllerUpdate(ControllerEvent event) { if (event instanceof RealizeCompleteEvent) { mediaPlayer.prefetch(); } else if (event instanceof PrefetchCompleteEvent) { Component video = mediaPlayer.getVisualComponent(); Component controls = mediaPlayer.getControlPanelComponent(); if (video != null) add(video, BorderLayout.CENTER); if (controls != null) add(controls, BorderLayout.SOUTH); revalidate(); repaint(); mediaPlayer.start(); } } }); mediaPlayer.realize();
- 移除无效依赖:pom中的
conviva-mediaplayer-sdk是安卓端AAR包,和桌面端JMF项目完全不兼容,直接删除该依赖避免类冲突。
内容的提问来源于stack exchange,提问作者coder_01
相关产品推荐
相关产品推荐

