简体   繁体   中英

AudioClip Issues when trying to play sounds on JFrame

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM