简体   繁体   English

尝试在JFrame上播放声音时出现AudioClip问题

[英]AudioClip Issues when trying to play sounds on JFrame

I've been trying to play sound1 and sound2 using AudioClips. 我一直在尝试使用AudioClips播放sound1和sound2。 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(); 当我尝试做Sound.sound1.loop();时 or Sound.sound1.play(); 或Sound.sound1.play(); I get a null pointer exception. 我得到一个空指针异常。 Same goes for sound2. 声音2也是如此。 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. 我已经反复浏览过stackoverflow以查找可能的修复程序,但是可能fileName始终返回null,或者我的URL某种程度上不正确。 That said, for all I know it could be anything. 就是说,就我所知,这可能是任何事情。 Any suggestions on how to fix this? 对于如何解决这个问题,有任何的建议吗?

The inclusion of src in your paths... 在您的路径中包含src ...

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. 是您的关键问题,一旦构建并打包了应用程序, src将不存在,您永远都不应引用src

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 ... 就个人而言,我会让Sound需要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 这样就不会混淆String含义,您可以从嵌入式资源,文件引用甚至从网络传递引用。

Also from memory, clip.start() creates it's own thread, so there's no need to create your own 同样从内存中, clip.start()创建它自己的线程,因此无需创建自己的线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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