Playing an mp3 file in BlueJ - java

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?

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();

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.

Related

How do I specify file path for Android's getExternalStorageState()?

I'm completely new to Android development and would like to index a file from the Android phone's external storage. I found some old code which used a deprecated method:
String file1 = Environment.getExternalStorageDirectory() + "/folder/file.blah";
I'm trying to rewrite this line and tried the Environment.getExternalFilesdir method but got a "cannot find symbol method" error. The only available method seems to be getExternalStorageState, but I can't figure out how to pass the file path argument in. How do I rewrite the deprecated code, using getExternalStorageState or otherwise? Thanks.
For getting directory of public file. you can use like below
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS);
docFile = new File(storageDir, docFileName);
Actually getExternalFilesDir() is not a part of Environment bundle. You can call it via the application context.
String file2 = getApplicationContext().getExternalFilesDir("folder")
The difference between these two are as follows
getExternalFilesDir():
This will return the path to files folder inside Android/data/data/your_package_name/. It is used to store any required files for your app.
getExternalStorageDirectory():
This returns the root path of you external SD card.
As far as the deprecation warning is concerned, Environment.getExternalStorageDirectory() or Environment.getExternalStoragePublicDirectory(), are deprecated. They still work, but will be removed soon, so you need to stop using those.

Slash character in file path creating exception in javafx media

I found many similar questions on this topic in this forum, but none of the solutions of those questions working for me and this problem is really making me frustrated.
I have the following method which should play a wav file when I call it.
Directory of the wav file is: ProjectFolder/src/resources/Sounds/click.wav
public static void Click()
{
String clickSound = "/resources/Sounds/click.wav";
Media hit = new Media(new File(clickSound).toPath().toString());
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
}
But it results in the following exception:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in path at index 0: \resources\Sounds\click.wav
at javafx.scene.media.Media.<init>(Media.java:385)
When I set the value of the string clickSound "resources/Sounds/click.wav" instead of "/resources/Sounds/click.wav", the exception says illegal character in path at index 9.
So I am guessing that it is considering '/' character as an illegal character. I tried using '\' instead of '/', but the result was same.
I do not want to change the location of the wav file for certain reason. How can access I access that wav file from ProjectFolder/src/resources/Sounds/click.wav and play it without any exception?
Any kind of help is appreciated.
Thanks in advance.
As stated in the documentation:
The source must represent a valid URI and is immutable. Only HTTP, HTTPS, FILE, and JAR URLs are supported. If the provided URL is invalid then an exception will be thrown.
You are passing in the path to a file, instead of a URI.
You almost certainly don't want a file here anyway; for example, when you deploy your application it will typically be deployed as a jar file, and the media will be an entry in that jar file (so it won't be a file in its own right at all). On top of that, the resources folder is typically part of the source code structure, and for obvious reasons the source code is not usually available at runtime.
Assuming your resources are being deployed to the root of the classpath, which is the usual setup, you need something like
String clickSound = "/Sounds/click.wav";
Media hit = new Media(getClass().getResource(clickSound).toExternalForm());
You listed the file as in directory "ProjectFolder/src/resource/Sounds/click.wav" but when trying to access you have "resources" instead of "resource"

Error in passing file location in Java [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I'm trying to create a media Player in Java.
In order to do that, I'm passing a string where my file is located but I am getting an error.
Operating System: MacOSX
IDE: Pycharm
#Override
public void start(Stage primaryStage) throws Exception{
String file="~/Users/ViditShah/IdeaProjects/MediaPlayer/src/sample/1.mp4";
Player player = new Player(file);
Scene scene = new Scene(player,720,480, Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
Player Class:
public class Player extends BorderPane {
Media media;
MediaPlayer player;
MediaView view;
Pane apane;
Player(String file)
{
media =new Media(file);
player = new MediaPlayer(media);
view = new MediaView(player);
apane.getChildren().add(view);
setCenter(apane);
}
}
The error is being shown in parsing the file String.
I guess I have made a mistake in locating my file path and failing to find solution.
You are apparently trying to pass a filesystem path to the Media constructor. According to the documentation:
The Media class represents a media resource. It is instantiated from the string form of a source URI.
and
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.
So it makes no sense at all to pass a filesystem path to the Media constructor. You have to pass it the string form of a URI.
There are two different scenarios that are possible here (and for some reason, you refuse to clarify which you are trying to do). Either you are trying to play a video which is part of your application, in which case the video will be included in the jar file for your application when it is deployed, or you are trying to play a video provided by the user at runtime.
In the former case, you basically need to load the video from wherever the JVM is loading classes (whether it be the file system, typically during development, or from a jar file, typically once the application is deployed). To do this, you get the URI from the class loader.
If the video is in the same package as the current class, you can do:
String videoURI = getClass().getResource("1.mp4").toURI().toString();
and pass that (via your Player constructor) to the Media constructor.
Or more generally, you can start the resource name with a /, in which case it will be searched relative to the classpath:
String videoURI = getClass().getResource("/sample/1.mp4").toURI().toString();
On the other hand, if you are playing a video that the user provides, you can create a URI from a File object:
File file = ... ;
String videoURI = file.toURI().toString();
For example, you might do:
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("mp4 video files", "*.mp4"));
File file = chooser.showOpenDialog(primaryStage);
if (file != null) {
String videoURI = file.toURI().toString();
// ...
}

Converting a Jar-URI into a nio.Path

I'm having trouble coverting from a URI to a nio.Path in the general case. Given a URI with multiple schemas, I wish to create a single nio.Path instance to reflect this URI.
//setup
String jarEmbeddedFilePathString = "jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml";
URI uri = URI.create(jarEmbeddedFilePathString);
//act
Path nioPath = Paths.get(uri);
//assert --any of these are acceptable
assertThat(nioPath).isEqualTo("C:/Program Files (x86)/OurSoftware/OurJar_x86_1.0.68.220.jar/com/our_company/javaFXViewCode.fxml");
//--or assertThat(nioPath).isEqualTo("/com/our_company/javaFXViewCode.fxml");
//--or assertThat(nioPath).isEqualTo("OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml")
//or pretty well any other interpretation of jar'd-uri-to-path any reasonable person would have.
This code currently throws FileSystemNotFoundException on the Paths.get() call.
The actual reason for this conversion is to ask the resulting path about things regarding its package location and file name --so in other words, as long as the resulting path object preserves the ...com/our_company/javaFXViewCode.fxml portion, then its still very convenient for us to use the NIO Path object.
Most of this information is actually used for debugging, so it would not be impossible for me to retrofit our code to avoid use of Paths in this particular instance and instead use URI's or simply strings, but that would involve a bunch of retooling for methods already conveniently provided by the nio.Path object.
I've started digging into the file system provider API and have been confronted with more complexity than I wish to deal with for such a small thing. Is there a simple way to convert from a class-loader provided URI to a path object corresponding to OS-understandable traversal in the case of the URI pointing to a non-jar file, and not-OS-understandable-but-still-useful traversal in the case where the path would point to a resource inside a jar (or for that matter a zip or tarball)?
Thanks for any help
A Java Path belongs to a FileSystem. A file system is implemented by a FileSystemProvider.
Java comes with two file system providers: One for the operating system (e.g. WindowsFileSystemProvider), and one for zip files (ZipFileSystemProvider). These are internal and should not be accessed directly.
To get a Path to a file inside a Jar file, you need to get (create) a FileSystem for the content of the Jar file. You can then get a Path to a file in that file system.
First, you'll need to parse the Jar URL, which is best done using the JarURLConnection:
URL jarEntryURL = new URL("jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml");
JarURLConnection jarEntryConn = (JarURLConnection) jarEntryURL.openConnection();
URL jarFileURL = jarEntryConn.getJarFileURL(); // file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar
String entryName = jarEntryConn.getEntryName(); // com/our_company/javaFXViewCode.fxml
Once you have those, you can create a FileSystem and get a Path to the jar'd file. Remember that FileSystem is an open resource and needs to be closed when you are done with it:
try (FileSystem jarFileSystem = FileSystems.newFileSystem(jarPath, null)) {
Path entryPath = jarFileSystem.getPath(entryName);
System.out.println("entryPath: " + entryPath); // com/our_company/javaFXViewCode.fxml
System.out.println("parent: " + entryPath.getParent()); // com/our_company
}

Load file in java with special path name

i try to play an mp3 from an location on my harddrive.
The file is located in here:
C:\Itunes\Music\Eminem\The Eminem Show [Explicit]\18 'Till I Collapse [Explicit].mp3
There are a lot of special characters in this path like [ and '. When i try to load the file with following code:
path = URLEncoder.encode(path, "UTF-8");
Media hit = new Media("file:///"+path);
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
i get an "illegal character" error in pathname.
My operating system is windows 8.
I'm very new to java and hope i find some help.
I believe you need to encode your URI
See: http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx

Categories

Resources