问题
I've been trying to play sound1 and sound2 using AudioClips. This is my code:
import javax.sound.sampled.*;
public class Sound {
private Clip clip;
public static final Sound sound1 = new Sound("src/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("src/Sounds/Classic Horror 3.mp3");
public Sound (String fileName) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(Sound.class.getResource(fileName));
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
public void play() {
try {
if (clip != null) {
new Thread() {
public void run() {
synchronized (clip) {
clip.stop();
clip.setFramePosition(0);
clip.start();
}
}
}.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop(){
if(clip == null) return;
clip.stop();
}
public void loop() {
try {
if (clip != null) {
new Thread() {
public void run() {
synchronized (clip) {
clip.stop();
clip.setFramePosition(0);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
}
}.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isActive(){
return clip.isActive();
}
}
When I try to do Sound.sound1.loop(); or Sound.sound1.play(); I get a null pointer exception. Same goes for sound2. Here are the exact errors messages:
java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidiFileReader.java:207)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:841)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:178)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1147)
at Sound.<init>(Sound.java:12)
at Sound.<clinit>(Sound.java:7)
at IntroductionComponent.<init>(IntroductionComponent.java:54)
at IntroductionGUI.main(IntroductionGUI.java:9)
java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidiFileReader.java:207)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:841)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:178)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1147)
at Sound.<init>(Sound.java:12)
at Sound.<clinit>(Sound.java:8)
at IntroductionComponent.<init>(IntroductionComponent.java:54)
at IntroductionGUI.main(IntroductionGUI.java:9)
I have repeatedly browsed stackoverflow to look for possible fixes, however it may be that fileName returns null constantly, or that my URL's are somehow incorrect. That said, for all I know it could be anything. Any suggestions on how to fix this?
回答1:
The inclusion of src
in your paths...
public static final Sound sound1 = new Sound("src/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("src/Sounds/Classic Horror 3.mp3");
is your key problem, src
won't exist once the application is build and package, you should never refer to src
ever.
You should probably be using something more like...
public static final Sound sound1 = new Sound("/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("/Sounds/Classic Horror 3.mp3");
public Sound (String fileName) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(getClass().getResource(fileName));
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
Personally, I'd make Sound
require a URL
...
public Sound (URL url) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
This way there's no confusion over what String
means and you can pass a reference from embedded resources, file references or even from the net
Also from memory, clip.start()
creates it's own thread, so there's no need to create your own
来源:https://stackoverflow.com/questions/35951496/audioclip-issues-when-trying-to-play-sounds-on-jframe