javaeclipseaudiojavasound

Trying to play a sound in java 8 using clip is throwing java.lang.NullPointerException


I'm currently programming a small game, and am trying to implement background music. I'm quite new to visual/audio in Java, and after doing some research online I found that Clip would be an option that would be compatible with how I'm doing my graphics. So, I followed a tutorial of how to set it up/use it, resulting in this 'Sound' class:

import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.*;

public class Sound implements LineListener {
    
    boolean isPlaybackCompleted;
    int playMode;
    
    public Sound(int mode) {
        playMode = mode; // 0 = background music
    }
    
    @Override
    public void update(LineEvent event) {
        if (LineEvent.Type.START == event.getType()) {
            isPlaybackCompleted = false;
            System.out.println("Playback started.");
        } else if (LineEvent.Type.STOP == event.getType()) {
            isPlaybackCompleted = true;
            System.out.println("Playback completed.");
        }
    }
    
    public void playSound(String soundName) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("./Sounds/facilityIndoors.wav");
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(inputStream);
        AudioFormat audioFormat = audioStream.getFormat();
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
        Clip audioClip = (Clip) AudioSystem.getLine(info);
        audioClip.addLineListener(this);
        audioClip.open(audioStream);
        audioClip.start();
        switch(playMode){
        case 0:
            if(isPlaybackCompleted == true) {
                
            }
        }
        audioClip.close();
        audioStream.close();
    }
}

(Note that the 'soundName' argument for playSound is something I'm hoping to implement later so I can switch between tracks based on a variable shared with the current map name and is currently unused, I've just hard coded the path to a file that already exists for now for testing)

And I have and instantiation and function call in my main

        Sound music = new Sound(0);
        music.playSound(map.currentMap);

When I try and call the playSound function though, this error throws:

Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:209)
    at java.desktop/javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1006)
    at Sound.playSound(Sound.java:37)
    at Program.main(Program.java:22)

At first I thought I had spelt the file path wrong, but after double checking my spelling seems to be correct, as shown here: Image of file path and file name 'Global Research FacilityJava8' is my project folder, and my image references seem to start from that level, so maybe Clip doesn't start from the project folder and that could be the issue, but if it is I don't know how to resolve it.

I have tried checking the file path for spelling errors, and have tried omitting some of the symbols from the start (E.G just 'Sounds/facilityIndoors.wav' or '/Sounds/facilityIndoors.wav'), but the error still persisted. While checking the list of possible duplicates before posting this, I have also found a post talking about putting all of my resource folders into one 'resources' folder and add it to the build path, which I have now tried, but to no avail, still throwing the same error. (file path is now 'resources/Sounds/facilityIndoors.wav')


Solution

  • I had faced this same issue, but instead of finding a way to fix it, I decided to work around it by copying the audio file out onto a location on my PC.

    try this code to copy the file

    File audio = new File("C://somewhere//audio.wav").mkdir();
    Files.copy(getClass().getResourceAsStream("resources/Sounds/facilityIndoors.wav"), Paths.get("C://somewhere//audio.wav"), StandardCopyOption.REPLACE_EXISTING);
    

    and now just use the audio file like so

    AudioInputStream audioStream = AudioSystem.getAudioInputStream(audio));
    Clip audioClip  = AudioSystem.getClip();
    audioClip.open(audioStream);