The audio file that I am using is found here: http://www.orangefreesounds.com/loud-alarm-clock-sound/
This is what my file structure looks like in my Eclipse IDE:
The audio file plays perfectly fine when I run it in my IDE, but not when I export it as a JAR file. I have already checked and found that the audio file is inside the JAR file.
I am using the terminal command java -jar Sandbox.jar &
to run the JAR file. The program seems to be able to find the file (since it is not throwing an IOException), but does not seem to be able to perform playback.
Why is this problem happening and how can I fix it?
Okay, so actually, the JAR file is able to play the audio file when run in cmd
or PowerShell
on Windows 8.1, but not in the terminal of Ubuntu 14.04 for some reason. This whole time, I have been trying to run the JAR file in Ubuntu 14.04.
I have confirmed the issue of the JAR files only working on a Windows 8.1
system. Both of the code snippets in this question DO NOT WORK, while both of MadProgrammer's solutions work.
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.*;
public class Sandbox
{
public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException
{
URL url = Sandbox.class.getResource("/sound-effects/alarmSoundClip.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
}
}
One attempted solution (as suggested by Andrew Thompson) was to write this.getClass().getResource( ... )
instead of Sandbox.class.getResource( ... ):
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.*;
public class Sandbox
{
public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException
{
new Sandbox();
}
public Sandbox() throws UnsupportedAudioFileException, IOException, LineUnavailableException
{
URL url = this.getClass().getResource("/sound-effects/alarmSoundClip.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
}
}
Adding clip.drain()
after clip.start()
seems to have worked okay for me (IDE and command line both with and without &
)
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Sandbox {
public static void main(String[] args) {
try {
URL url = Sandbox.class.getResource("/sound-effects/Loud-alarm-clock-sound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
System.out.println("Drain...");
clip.drain();
System.out.println("...Drained");
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException exp) {
exp.printStackTrace();
}
}
}
Now, having said that, I have found drain
a little unreliable in the past, especially when there are multiple sounds playing in which case I tend to use a LineListener
For example...
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Sandbox {
protected static final Object LOCK = new Object();
public static void main(String[] args) {
try {
URL url = Sandbox.class.getResource("/sound-effects/Loud-alarm-clock-sound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
System.out.println(event.getType());
if (event.getType() == LineEvent.Type.STOP) {
synchronized (LOCK) {
LOCK.notify();
}
}
}
});
clip.start();
synchronized (LOCK) {
LOCK.wait();
}
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException exp) {
exp.printStackTrace();
}
}
}