How to play sound in JavaFX?

8.9k Views Asked by At

I'm experimenting with JavaFX making a small game.

I want to add sound. How?

I tried MediaPlayer with media defined with relative source attribute like:

attribute media = Media{
    source: "{__FILE__}/sound/hormpipe.mp3"        
}
attribute player = MediaPlayer{
    autoPlay:true
    media:media
}

It doesn't play. I get

FX Media Object caught Exception com.sun.media.jmc.MediaUnavailableException: Media unavailable: file: ... Sound.class/sound/hormpipe.mp3

6

There are 6 best solutions below

0
On

This worked for me:

MediaPlayer audio = new MediaPlayer(
    new Media(
        new File("file.mp3").toURI().toString()));

Source file should be in project's root directory (not src, not dist).

0
On

Also note that {__DIR__} includes the trailing /, so try this instead:

attribute media = Media{
source: "{__DIR__}sound/hormpipe.mp3"}

EDIT: I did some digging, and apparently, the source of a Media object has to be either a remote URL, or an absolute file path, since media files aren't allowed in JARs (something I hope gets changed with future releases, since I really like JavaFX and want to be able to make desktop apps with it). See: JavaFX FAQs.

0
On

Just a guess, but I think your {__FILE__} will expand to the name of your file. Try replacing it with {__DIR__}.

0
On

OK, having used this question to get MP3 audio working (kinda), I've learned the following (not much).

1) Audio for compressed formats is very platform dependent. My continually upgraded Mint 17.1->18 machine plays mp3 fine using Media and MediaPlayer. Fresh installs of Mint 18 won't (with the dev tools).

So use .wav files.

Media sound=new Media(new File("noises/roll.wav").toURI().toString());
MediaPlayer mediaPlayer=new MediaPlayer(sound);
mediaPlayer.play();

2) One of the things you need to be aware of with Media/MediaPlayer is that in order to play multiple times (repeatedly or all at once ie, on a button press/whatever in a game) you have to spawn N number of MediaPlayer objects, and each one will play once and then stop.

So use javafx.scene.media.AudioClip

AudioClip soundMyNoise = new AudioClip(new File("noises/roll.wav").toURI().toString());
soundMyNoise.play();

AudioClip also has its issues, which include storing the raw audio data in RAM all at once instead of buffering. So there is the possibility of excessive memory use.

No matter which method you end up going with, one thing to be critically aware of was mentioned by daevon earlier - the path issue. With NetBeans, you have NetBeansProjects/yourproject/src/yourproject/foo.java. The sounds in the example above go in NetBeansProjects/yourproject/noises/roll.wav

1
On

Just a guess, but is that file "hornpipe.mp3" and not "hormpipe.mp3" (with an m)?

0
On
var player = javafx.scene.media.MediaPlayer {
    repeatCount: javafx.scene.media.MediaPlayer.REPEAT_FOREVER
    media: Media { source: "{\_\_DIR\_\_}clip.wav"
    };
};
player.play();

You have to incluye the audio file in the build/compiled directory so Netbeans can pack it into the jar file.