问题
I want to load an mp3 file from inside the jar file itself and then play it with JLayer. When I try to do it, I either get a NullPointerException or a FileNotFoundException. Any idea on how to fix this?
//MP3Player.java
package Music;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javazoom.jl.player.Player;
public class MP3Player extends Thread
{
private String filename;
private Player player;
private Thread mp3Thread;
private boolean playing;
private boolean locked;
// constructor that takes the name of an MP3 file
public MP3Player()
{
this.filename = "";
mp3Thread = null;
playing = true;
locked = true;
}
public void run()
{
while (playing)
play();
}
public void play()
{
if (!locked)
{
if (filename != null && filename != "")
{
try
{
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
player = new Player(bis);
mp3Thread = new Thread()
{
public void run()
{ try { player.play(); } catch (Exception e) { System.out.println(e); } }
};
mp3Thread.start();
// mp3Thread.join();
} catch (Exception e) { System.out.println(e); }
}
}
}
public void changeMusic(String newGuy)
{
locked = true;
filename = "";
try
{
if (player != null)
player.close();
mp3Thread = null;
filename = newGuy;
locked = false;
}
catch (Exception e) {}
}
public void close()
{
locked = true;
playing = false;
try
{
if (player != null)
player.close();
if (mp3Thread != null)
mp3Thread = null;
} catch (Exception e) {}
}
// MusicHandler.java
package Music;
import java.io.File;
import javax.swing.*;
public final class MusicHandler {
public MusicHandler() {
}
public void PlayBoundlessMusic() {
try {
String myFile = (getClass().getResource("/Boundless/Twilight.mp3").getPath());
MP3Player player = new MP3Player();
player.changeMusic(myFile);
player.play();
} catch (Exception e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, e);
}
}
private void PlayMusic(File f) {
}
}
回答1:
You MP3 is what is called an embedded resource, it does not act like a file (in fact it can't even be considered a file). We sometimes treat them like a virtual file.
Instead of trying to read the file using a FileInputStream
you need to obtain a InputStream
to the embedded resource.
You should use getClass().getClassLoader().getResourceAsStream(fileName)
which will return an InputStream
...
Remember, if you open a stream, you're responsible for closing it...
InputStream fis = null;
BufferedInputStream bis = null;
try
{
fis = getClass().getClassLoader().getResourceAsStream(fileName);
bis = new BufferedInputStream(fis);
player = new Player(bis);
mp3Thread = new Thread()
{
public void run()
{ try { player.play(); } catch (Exception e) { System.out.println(e); } }
};
mp3Thread.start();
// mp3Thread.join();
} catch (Exception e) { System.out.println(e); }
} finally {
try {
fis.close();
} catch (Exception e) {}
try {
bis.close();
} catch (Exception e) {}
}
Of course, you could take advantage of Java 7's auto close (or try-with-resources) feature
来源:https://stackoverflow.com/questions/14180023/loading-an-mp3-file-with-jlayer-from-inside-the-jar