1

I'm trying to play an mp3 file in BlueJ following this Stack question answer: Playing .mp3 and .wav in Java?

I have the exact same code except the file name. Here is my code:

String bip = "Johnny.mp3";
             Media hit = new Media(bip);
             MediaPlayer mediaPlayer = new MediaPlayer(hit);
             mediaPlayer.play();

I CAN compile this, but when the program tries to run it I get an exception. Here is the entire error:

java.lang.IllegalArgumentException: uri.getScheme() == null! uri == 'Johnny.mp3'
at com.sun.media.jfxmedia.locator.Locator.<init>(Locator.java:211)
at javafx.scene.media.Media.<init>(Media.java:391)
at Game.goRoom(Game.java:282)
at Game.processCommand(Game.java:167)
at Game.play(Game.java:130)

Personally, I think this is related with the file path I have given. I know that the file exists in my project map but I'm very uncertain on the pathway they want, do they want a full pathway all the way from file:// or just the sound-files name which is what I have done? Note that this project doesn't have any resource folder like Eclipse projects have since this is how the IDE handles it files. The sound-file just lies in the same folder as all the classes so it's not sorted in any manner.

I have checked around, and it seems that if this is not my problem it would be that my JavaFX is not initialized. If this is the case, how would I go about it and how would the syntax look like?

Community
  • 1
  • 1
Rawand
  • 23
  • 5
  • So you're using `JavaFX`'s `MediaPlayer`, it requires a valid `URL` (why it doesn't just take a flippen `URL` class as the parameter and save use the issues I don't know). You could try using `new File(bip).toURI().toURL().toString()` – MadProgrammer Nov 11 '15 at 22:59
  • I can't do this without throw, are you suggesting that I do that? – Rawand Nov 11 '15 at 23:04
  • If you want this to work, then yes. Either you will need to throw the resulting exception or catch it – MadProgrammer Nov 11 '15 at 23:08

2 Answers2

2

Media takes your String value and tries to make a URI. Why the method doesn't just require you to pass it a URI (or URL) directly, I don't know.

The documentation outlines this rather well...

Constructs a Media instance. This is the only way to specify the media source. The source must represent a valid URI and is immutable. Only HTTP, FILE, and JAR URLs are supported. If the provided URL is invalid then an exception will be thrown. If an asynchronous error occurs, the error property will be set. Listen to this property to be notified of any such errors.
...
Constraints:

  • The supplied URI must conform to RFC-2396 as required by java.net.URI.
  • Only HTTP, FILE, and JAR URIs are supported.

See java.net.URI for more information about URI formatting in general. JAR URL syntax is specified in java.net.JarURLConnection.

Parameters:
source - The URI of the source media.
Throws:
- java.lang.NullPointerException - if the URI string is null.
- java.lang.IllegalArgumentException - if the URI string does not conform to RFC-2396 or, if appropriate, the Jar URL specification, or is in a non-compliant form which cannot be modified to a compliant form.
- java.lang.IllegalArgumentException - if the URI string has a null scheme.
- java.lang.UnsupportedOperationException - if the protocol specified for the source is not supported.
...

And if we have a look at the source, you can see it trying to wrap the String in a URI class...

public Media(@NamedArg("source") String source) {
    this.source = source;

    URI uri = null;
    try {
        // URI will throw NPE if source == null: do not catch it!
        uri = new URI(source);
    } catch(URISyntaxException use) {
        throw new IllegalArgumentException(use);
    }

So, depending on where the file is actually stored, you could use something like

Media hit = new Media(new File(bip).toURI().toURL().toString());
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();

This also assumes that "Johnny.mp3" is in the current working directory of your program.

I say "depending" as you would use a different approach for media files which were located internally (bundled) with your application to those which are external.

In which case you might use something like...

Media hit = new Media(getClass().getResource(bip).toExternalForm());
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Im getting close, but I'm getting an error which says "Toolkit not initialized", do you know how to implement this toolkit? – Rawand Nov 12 '15 at 00:26
  • This makes an assumption that you want to use JavaFX (GUI framework), you'd need to start by creating a class which extends the `Application` class and call the `static` `launch` method. An alternative would be to use [JZoom's JLayer](http://www.javazoom.net/javalayer/javalayer.html) or [JZoom's MP3 SPI for Java's Audio API](http://www.javazoom.net/mp3spi/mp3spi.html) – MadProgrammer Nov 12 '15 at 00:30
1

Here ya go:

MediaPlayer yourPlayer = new MediaPlayer(new Media(Paths.get("yourAudioFile").toUri().toString()));

Make sure to add the file extension onto the audio file! Also, import the following:

import java.nio.file.Paths;

I'm assuming you have the Media and MediaPlayer classes imported.

Rahul S.
  • 55
  • 1
  • 8
  • 1
    Basically, it converts the file's location into a URI, and then converts it back into a string, which is taken by the Media constructor. This is handy in that you can move the folder containing the class and audio file around and you won't have to change any of your code. – Rahul S. Nov 11 '15 at 23:55
  • 1
    does "yourAudiofile " have to be the full path? because this is not working if I only have the line of code which you have given me. – Rawand Nov 12 '15 at 00:20
  • 1
    Nah. It just has to be the name of the file and the extension, of course. **EDIT:** Like so: "Johnny.mp3" – Rahul S. Nov 12 '15 at 01:24