I have this slightly altered a sound manager from another question How can I play sound in Java?. Here it is:
public static synchronized void playSound(final String url)
{
new Thread(new Runnable()
{
public void run()
{
try
{
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("sound/" + url));
clip.open(inputStream);
clip.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
Whenever I call this method I get a javax.sound.sampled.LineUnavailableException in the clip.open(inputStream);. What can I do to repair it? Why does it not work?
Related
I made a java program and wanted a background music so I used this function
public static void playSound(final String url) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem
.getAudioInputStream(getClass().getResourceAsStream("/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
only problem is when I try to run the 27 minute wav file, it speeds it up really fast
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
I am having trouble stopping one thread and starting another one. I have created two threads. One of them is first run from the main method. It then takes user input and if the desired input is provided, thread one (sound) is supposed to stop and start thread two (sound2). From the code below, thread two does start playing after the correct input is provided during thread one. But thread one does not stop. I can hear audio files from both thread one and thread two playing. Please help.
public class crytask {
public static void main(String args[]) throws InterruptedException {
Runnable sound = new sound();
final Thread soundthread = new Thread(sound);
soundthread.start();
int count = 0;
System.out.println("Enter");
Scanner reader = new Scanner(System.in);
int a = reader.nextInt();
if (a==12)
soundthread.interrupt();
System.out.println("this thread is cancelled");
Runnable sound2 = new sound2();
final Thread soundthread2 = new Thread(sound2);
soundthread2.start();
int count2 = 0;
System.out.println("Enter");
Scanner reader2 = new Scanner(System.in);
int b = reader2.nextInt();
if (b==12)
soundthread2.interrupt();
}}
class sound implements Runnable {
#Override
public void run() {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
System.out.println("Cancelled 1!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
class sound2 implements Runnable {
#Override
public void run() {
try {
AudioInputStream audioInputStream2 = AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream2);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
System.out.println("Cancelled 2!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
Try stopping the clip when the thread is interrupted, adding clip.close() to the catch clause that catches the interruptedException, like this:
class sound implements Runnable {
#Override
public void run() {
Clip clip = null; // take the declaration of the clip variable out of the try - catch
try {
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
clip.stop(); // <--- ADD THIS LINE
System.out.println("Cancelled 1!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
I have written a method in java to play a sound. It works fine on my ubuntu laptop but doesnt work on windows. There is no error but i think it might be bypassing the drain method on windows for some reason.
public static void runOnce(final String location) {
new Thread(new Runnable() {
public void run() {
try {
File audioFile = new File(Game.gameFolder + "/sounds/" + location);
final AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
final Clip audioClip = (Clip) AudioSystem.getLine(info);
audioClip.open(audioStream);
audioClip.start();
audioClip.drain();
try {
audioClip.close();
audioStream.close();
} catch (Exception e) {
System.out.println("heyeyeyeyye");
}
System.out.println("sound method ran");
} catch(Exception e) {}
}
}).start();
}
thanks -Tyler
EDIT:
i remember actually it worked on windows before i used drain but after a certain amount of time it wouldnt load anymore so i switched to drain
I suggest you use try-with-resources and that you join() the Thread you start and never swallow the message from your Exception. Something like,
public static void runOnce(final String location) {
File audioFile = new File(Game.gameFolder + "/sounds/" + location);
Thread t = new Thread(new Runnable() {
public void run() {
try (AudioInputStream audioStream = AudioSystem
.getAudioInputStream(audioFile);) {
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
try (Clip audioClip = (Clip) AudioSystem.getLine(info);) {
audioClip.open(audioStream);
audioClip.start();
audioClip.drain();
}
System.out.println("heyeyeyeyye");
System.out.println("sound method ran");
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
t.join();
}
I'm trying to use the code which available on: How can I play sound in Java?
but I can't post question there since this is a new account and only have 1 reputation.
original code:
public static synchronized void playSound(final String url) {
new Thread(new Runnable() { // the wrapper thread is unnecessary, unless it blocks on the Clip finishing, see comments
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream("/path/to/sounds/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
and this is my code:
package sound_test;
import javax.sound.sampled.*;
public class Main {
public static synchronized void playSound(final String url) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream("/path/to/sounds/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
public static void main(String[] args) {
// TODO code application logic here
playSound("C:\\warning_test.wav");
}
}
When I run the code i receive "null" as the output and no sound came out.
I've checked the file name and the path, it's correct.
screenshots:
http://puu.sh/pkYo
http://puu.sh/pkZl
Thank you in advance.
you could do
AudioInputStream inputStream=AudioSystem.getAudioInputStream(new File(url));
also add a delay after click.start(); i.e Thread.Sleep(4000);
or if you want to make sure it plays the entire audio sample you could use a simple snippet such as
import javax.sound.sampled.*;
import java.io.File;
public class Main implements LineListener {
private boolean done = false;
public void update(LineEvent event) {
if(event.getType() == LineEvent.Type.STOP || event.getType() == LineEvent.Type.CLOSE) {
done = true;
}
}
public void waitonfinish() throws InterruptedException {
while(!done) {
Thread.sleep(1000);
}
}
public static void playSound(final String url) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(url));
Main control = new Main();
clip.addLineListener(control);
clip.open(inputStream);
clip.start();
control.waitonfinish();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
public static void main(String[] args) {
// TODO code application logic here
playSound("C:\\warning_test.wav");
}
}
`
You copied the code entirely without noticing the in the original, it points to
path/to/sounds
since you give it the full path, u should replace it with just url:
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream(url));
EDIT:
I tried here and got null as well.
I changed it to create the audioInput from a file:
import java.io.File;
import javax.sound.sampled.*;
public class Main {
public static synchronized void playSound(final File file) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(file);
clip.open(inputStream);
clip.start();
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
}).start();
}
public static void main(String[] args) {
// TODO code application logic here
File file = new File("C:\\warning_test.wav");
playSound(file);
}