So my task is to create a small program that displays a list of media files and run these media files with default OS media player separately.
My current solution was to create a package that holds all media files, something like:
-com.media
|_a.mp4
|_b.mp4
The following code copies to a temp dir the selected mp4, then runs the default os media player:
public File copyTempMedia(File tempAppFolder, String videoName) {
URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
File from = new File(f.getPath());
File to = new File(tempAppFolder.getAbsolutePath());
try {
FileUtils.copyFileToDirectory(from, to);
} catch (IOException ex) {
Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Temp video copied: " + to.getAbsolutePath() + "/" + to.getName());
return to;
}
public void triggerMediaPlayer(String fileLocation) {
System.out.println("Triggering media player: " + fileLocation);
try {
if (OPERATIN_SYSTEM.contains("Linux")) {
Runtime.getRuntime().exec("sh -c " + fileLocation);
} else if (OPERATIN_SYSTEM.contains("Windows")) {
Runtime.getRuntime().exec("cmd /c " + fileLocation);
}
} catch (IOException ex) {
Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
When I run the program through Netbeans it works as espected, but when I do a clean/build
the run the .jar
created from the build, the media file doesn't seem to be read, so my questions are:
Thanks in advance.
So after running through console instead of double clicking jar, is get a null pointer exception in the line where I read the file:
URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName));
Why does it work in Netebeans but not on build/jar ?
Is there another place in the jar I could place the media files, so that they are read with no problem through getResource or getResourceAsStream ?
When you run the project in NetBeans, it isn't running the executable jar like java -jar yourproject.jar
. Instead it sets the classpath to build/classes sort of like java -cp build/classes com.media.YourMainClass
. This means your video files are actual files located in yourproject/build/classes/com/media, and they can be accessed as normal files in the filesystem and copied like a normal file. When you run from the jar, the files are packed in the jar file and can't be copied using simple file copy commands.
Instead of getting the URL by calling getClass().getResource()
, try getting an InputStream
by calling getClass().getResourceAsStream()
. You can then write a simple loop to copy the bytes from the input stream to your temporary file.
This snippet may be helpful:
BufferedInputStream result = (BufferedInputStream) getClass().getResourceAsStream("/com/media/a.mp4");
byte[] bytes = new byte[4098];
try {
result.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(new String(bytes));
You'll need to read the bytes in a loop or something but that should work without needing a separate jar.
I think it's not a good idea to put your media files in the jar because you need to rebuild the project if you want to change one and the jar size will grow.
Use:
File from = new File(String.format("%s/%s", Constants.MEDIA_LOCATION,videoName));
To load your files from the same folder as the jar.
If you want to keep the medias in the jar, create a Maven project and put the mp4 in src/main/resources. Use maven to create a fat jar and the src/main/resources will be included in the jar. See 'maven-shade-plugin' to configure the pom.xml and https://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/
Then you can use the others maven's great properties!
See Reading a resource file from within jar
Edit
After some tries, i can't get it right with 'getResource' from the jar.
The path you get from within the jar is like:file:/C:/.../JavaApplication4/dist/JavaApplication4.jar!/test.txt
and not recognized as a valid filesystem path.
You can use 'getResourceAsStream' and copy the file from the jar to the local folder.
InputStream in;
OutputStream out;
IOUtils.copy(in,out);
in.close();
out.close();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With