I'm having issues (like some others) with getting the JavaFX MediaPlayer component to play content (video/audio files of any container/encoding type) in Debian Jessie. I've tried and exhausted any potential solution to this problem (I have GLIB 2.28 installed, I've upgraded Java to u60, I've ensured all codec packages have been installed including libavcodec/libavformat/libavutil/etc., I'm at gtk2 2.18+). I don't know what else to do or try. I have a very simple application that works perfectly fine under Windows 7.
Here is the simple application:
public class MediaTest extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
Media media = new Media(new File("/path/to/file/test.flv").toURI().toString());
MediaPlayer player = new MediaPlayer(media);
MediaView view = new MediaView(player);
root.setCenter(view);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("For the love of God, please work");
primaryStage.setScene(scene);
primaryStage.show();
player.play();
}
public static void main(String[] args) {
launch(args);
}
}
The problem manifests on the creation of the MediaPlayer. After a few lengthy debugging sessions, I found that the exception that is internally generated is some permutation of MEDIA_UNSUPPORTED message, regardless of the media type or format, though the Exception that is caught lists it as
MediaException: UNKNOWN : com.sun.media.jfxmedia.MediaException: Could not create player!
I've tried just about everything I can think of. I have a sample video file encoded just about every way possible, and in a myriad of different containers. Nothing works. I have a sample audio file encoded in just about every way possible, with the same results.
Am I just SOL on getting MediaPlayer to work on Debian? If so, this is highly disappointing. I know it's nigh impossible to get something to work on Windows, Mac, and every distro of Linux, but Write Once Run Everywhere seems not to hold true for Java8.
EDIT: I have oracle's java8, not openjdk.
EDIT 2: The internal error seems to be coming from gstreamer.
Here are the args going into MediaException.getMediaException(Object source, int errorCode, String message):
source : com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia
errorCode : 265
message : ERROR_MEDIA_AUDIO_FORMAT_UNSUPPORTED
Mind the graphics drivers. For example, in Ubuntu 16.04, the AMD opensource graphics drivers seem incomplete, javafx video seems impossible.
I got it to work in this environment:
Ubuntu 14.04, intel chipset graphics, oracle jdk 8.
Installed libavcodec54 and libavformat54. Not it works (Graphics and sound OK). My test video: http://www.sample-videos.com/video/flv/720/big_buck_bunny_720p_1mb.flv
(container: MP4/M4a, video: H.264, sound: MPEG-4 AAC)
Related
I'm working on a JavaFX project in Netbeans that's currently around 3000 lines long, and I've packaged as an .exe regularly for testing but never come across an issue like this curious incident.
When packaging natively as a Windows .exe file, I found that after installing the .exe and launching my program I was getting a popup saying "Class {mypackage}/{mymainclass} not found." followed by "Failed to launch JVM."
Launching the program in Netbeans, packaging as an .exe, and launching the .jar in Powershell with "java -jar {app}.jar" all gave absolutely no errors. Even the .jar inside the installed application folder was fine, with no errors on the command line.
After a few hours of trawling through git commits and packaging natively, I managed to trace the issue down to a single line of code:
private static ComboBox choices = new ComboBox();
When I initialise the ComboBox in an initialiser, the program magically works after being installed from an .exe:
private static ComboBox choices;
{
choices = new ComboBox();
}
However, when I use a static initialiser (by placing static in front of the first curly brace), even though Netbeans states "initialiser can be static", I get the same error as before.
This is puzzling, because Java is obviously fine with the code itself, but after it's been through the native packager it will not launch. I've used plenty of similar lines of code to initialise static variables in other classes, with no ill effects.
I tried adding a similar line to the main class: private static CheckBox chkbox = new CheckBox();
It caused the exact same error after the .exe was installed (as before, the .jar was fine), but when I cut-and-pasted the line to a different class, it had no effect.
Interestingly, my main class already has a static boolean that is initialised in the same way that the ComboBox and CheckBox were: private static boolean someBool = true; but the boolean causes no problems.
Can anyone explain the reason behind this? Thank you.
Edit: I also tried packaging on a different machine, but it stopped working after the same git commit.
I'm using version 1.8.0_144 of the JDK and JRE.
Edit 2: here is the main class of a simple example that produces the error.
package testproject;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MainApplication extends Application {
private static CheckBox testCheckBox = new CheckBox(); // Causes error after launching from installed .exe
/* UNCOMMENT THIS SECTION AND REMOVE THE " = new CheckBox()" ABOVE TO FIX THE ERROR
{
testCheckBox = new CheckBox();
}
*/
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Empty window");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I would avoid creating JavaFX widgets in static initializers (such as a static field or static block), as this would create them when class is loaded, which might happen in any thread. You want that to happen in JavaFX Application Thread.
In your case it happens in main thread, which is definitely not correct.
Check this answer for more details about JavaFX application startup, and how threads are involved in the process.
Trying to initialize a JavaFX widget outside of "JavaFX Application Thread" is (to my understanding) undefined behavior, and might fail in many different ways (or succeed by luck). If that creation fails, then the class loading fails (because static init has failed), hence "class not found". Unfortunately, since this happens while loading main class, you don't get to see the initial error, just "class XXX not found".
Possibly in your case, the java launcher can deal with this initialization just fine, but the launcher used by your .exe is different. I'm not too surprised it fails. I'm equally surprised it works with regular java :)
I want to code a USB-Locker for any OS using usb4java. I can list all my devices, but if I want to use the HotPlug class made by Klaus Reimer I get the informaion:
"libusb doesn't support hotplug on this system"
Is there an alternitiv class, or an user code to do the same thing as the HotPlug class.
I am working on Windows 10 and it should run on this os as well, so programming in Linux or so is not an option to avoid this error.
thanks
I used the same example and had the same notification. Now I´m using usb4java-javax in version 1.2.0 and it works like this:
final UsbServices services = UsbHostManager.getUsbServices();
final UsbDeviceService usbDeviceService = new UsbDeviceService();
services.addUsbServicesListener(new UsbServicesListener() {
public void usbDeviceAttached(UsbServicesEvent usbServicesEvent) {}
public void usbDeviceDetached(UsbServicesEvent usbServicesEvent) {}
}
Be sure your application is running all the time.
I've got Gradle projects and 2 IDE's: NetBeans and IntelliJ. NetBeans works perfectly with this project, no errors found.
But IntelliJ in the same project throws exception:
[Assets] error: com.badlogic.gdx.utils.GdxRuntimeException: File not found: ./images/enemy.atlas (Internal)
Here is Java class:
public class Assets {
public static AssetManager assetManager;
public Assets() {
assetManager = new AssetManager();
try {
assetManager.load("./images/enemy.atlas", TextureAtlas.class);
assetManager.load("./images/buttons.atlas", TextureAtlas.class);
assetManager.load("./fonts/000.fnt", BitmapFont.class);
assetManager.load("./fonts/111.fnt", BitmapFont.class);
assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
assetManager.load("./world/level1/map.tmx", TiledMap.class);
assetManager.finishLoading();
} catch (GdxRuntimeException e) { if (Variables.isDebug) System.err.println("\n[Assets] error: " + e + "\n"); }
}
}
It is simple, right? So, I've looked through *.gradle files and noticed that gradle knows where to search for my assets:
project.ext.assetsDir = new File("../android/assets");
I've remade project especially for IDEA (using gdx-setup.jar), but same problem arises. I'm confused and asking for advise!
P.S. AssetManager is a class of LibGDX 1.1.0 library.
Have you tried ommiting the ./ at the beginning of the path? See: https://github.com/libgdx/libgdx/wiki/Managing-your-assets#loading-assets
./ usually references the current directory, but I don't know how libgdx handles it. I can't post this as a comment somehow.
I had similar problem. After 3 hours of being angry i realized that path is case sensitive.
Example for tile map:
Android assets file structure:
assets/Maps/Desert.tmx
//Work as desktop luncher but not on android
TiledMap tiledMap = new TmxMapLoader().load("maps\\Desert.tmx");
//Works on android and dektop
TiledMap tiledMap = new TmxMapLoader().load("Maps\\Desert.tmx");
Second thing which I noticed is that path shouldn't start with
./
../
.\\
..\\
//Enough
"Maps\\Desert.tmx"
//Too much
".\\Maps\\Desert.tmx"
One of the possible way outs for IDEA is to set the Working directory for the Desktop run configuration to your android/assets/ folder.
You need to tell the "desktop module" to look for assets in the "android module." I forget the exact steps to do this...
I have a swing application and inside i added a JFXpanel from javafx2 jdk1.7_17 (also tried 1.7_15). i do create the JFXpanel in EDT and add it on swing tabbed pane, then add the scene to the FXPanel in javaFX thread as shown in the doc. If i run the application once everything is fine, if i stop the application and run it again the jvm crashes saying Problematic Frame libdbus. After closing the application no matter how many times i try the jvm will crash complaining about dbus usually but not always:
JRE version: 7.0_17-b02
Java VM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode linux-amd64 compressed oops)
Problematic frame:
C [libc.so.6+0x12fbd6]Java Result: 134
Sometimes i get this:
GConf-WARNING **: Got Disconnected from DBus.
If i restart the pc it runs ok the first time again and then if i close / re-run it keeps crashing at start up. I am running fedora 18 and i believe it maybe OS related since java FX is using native libs.
FXPanelJob fxPanelJob = new FXPanelJob(fxPanel);
tabbedPane = new JTabbedPane();
tabbedPane.addTab("table", fxPanel);
Platform.runLater(fxPanelJob);
private class FXPanelJob implements Runnable {
private JFXPanel fxPanel;
private volatile boolean done = false;
public FXPanelJob(JFXPanel fxPanel) {
this.fxPanel = fxPanel;
}
#Override
public void run() {
initFX(fxPanel);
done = true;
}
private void initFX(JFXPanel fxPanel) {
// This method is invoked on the JavaFX thread
VBox vbox = new VBox();
Scene scene = new Scene(vbox, 300, 200);
TableView<ReportRaw> table = new Table();
vbox.getChildren().addAll(table);
VBox.setVgrow(table, Priority.ALWAYS);
fxPanel.setScene(scene);
}
}
Since the first time is running i just guessed that might be a problem with shutting down the javafx on application exit. On windowClosing event i have:
Platform.runLater(new Runnable(){ public void run(){
Platform.exit();
});
Update:
It turns out its not a java fx problem, i switched to JDK 6 and everything is fine. I think it is specific to OS problem. Using jdk 7 without java fx could still trigger jvm crash.
if anyone knows what might be causing the jvm to crash i would appreciate.
Thank you in advance
Update 2
found a similar post, it seems to have been solved but i am not sure:
http://ubuntuforums.org/showthread.php?t=1697231&page=3
use this for jvm arguement -XX:-UseCompressedOops. i'll post it as an answer when i make sure its not crashing anymore.
Update 3
Couldn't solve it i commented out my javafx code as a solution. I believe its EDT related but i cant guarantee. it seems to be occuring several lines after the JavaFx panel is added on swing app. Not always at the same line. If removed everything works, so i guess its still an immature project.
I hitherto used the following code to set the Application Name (in the top "System" menu bar) on my Apple MacBook. (Actually, I think I copied this from stackoverflow.)
Basically, have a seperate AppLauncher class that uses System.setProperty() to set the application name before creating a new Runnable for the app itself.
Worked just fine.
However, since I downloaded and started using JDK 1.7, the solution stopped working - I'm getting the Class Name instead of the App Name in the menu, just like before I found that solution. I tried googling it, but to no avail.
Here is the defunct code that used to work under JDK 1.6, reduced to the relevant parts:
public class AppLauncher {
public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name",
"My Application");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainWindow();
}
});
}
}
Thanks for suggestions!
ETA: invoking with java -Dapple.laf.useScreenMenuBar=true still works. Pu8tting the property into Info.plist might work, but I haven't tried it yet.
It appears that setting the property using -D solves the problem.
java -Dapple.laf.useScreenMenuBar=true …
Other approaches are mentioned in this related answer.
I couldn't get the Info.plist or -D approaches to work (I'm working on distributing a JRuby App, that might have something to do with it), but for me passing the -Xdock:name parameter as mentioned in this article under the section "More tinkering with the menu bar" seemed to work great.
Example: -Xdock:name="My Application"