i wrote a little sound class where i can make a sound and toggle it and stuff but im not too great and i had to at least temporarily scrap it. i tried a little method to load sound and play it and then when it ends to unload it. it causes a lot of lag though. the class i had before would do the same thing as far as i can see but it didnt discard the sound properly and the soundswouldnt load anymore. heres my method thats causing ober lag but is working for what it should do. i need help refining it please.
public static void runOnce(final String location) {
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();
new Thread(new Runnable() {
public void run() {
while (audioClip.isActive()) {}
try {
audioClip.close();
audioStream.close();
} catch (Exception e) {}
}
}).start();
} catch (Exception e) {}
}
Related
I am currently using this function to play .WAV files
public void playSound(String sound){
try {
// Open an audio input stream.
URL url = this.getClass().getClassLoader().getResource(sound);
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
// Get a sound clip resource.
Clip clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
The problem is that no sound is being played when I call the function on a file, no errors or exceptions are thrown or whatsoever the program just starts and stops, no sound plays, I tried with a lot of different .WAV files with no success.
The programm stops before it has time to play the sound since start is non-blocking.
Try the following :
clip.start();
clip.drain();
clip.close();
This works for me:
public void sound() {
try{
AudioInputStream ais = AudioSystem.getAudioInputStream(new File("./sounds/player-laser.wav"));
Clip test = AudioSystem.getClip();
test.open(ais);
test.loop(0);
}catch(Exception ex){
ex.printStackTrace();
}
}
I have problem with my app. When I run app in Eclipse, sound played well, but if I export app to runnable jar, sound doesn't work.
Method, where sound is played:
public static synchronized void playSound()
{
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(getClass().getResourceAsStream("sound.wav"));
clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
}
catch (Exception e)
{
System.err.println(e.getMessage());
}
}
}).start();
}
Where can be a mistake?
The problem is in this
AudioInputStream inputStream = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("sound.wav"));
in JAR file isn't working getResourceAsStream for any reason. So I replace it with getResource:
AudioInputStream inputStream = AudioSystem.getAudioInputStream(getClass().getResource("sound.wav"));
and this works fine.
I'm trying to add sound to a game I've been working on, and I'm having trouble getting the sounds to play more than once. I think I've worked out the cause, but I'm not sure how to solve it. I'm using an enumerator I found while searching for a Java sound tutorial.
The problem is that I'm calling the sound within a thread, in my update() method, and that each time I call the play() method of the sound, it starts the clip over. The first time it's called, the sound plays fine (I may get a bit of a freeze), but all attempts afterwards to play the sound fail. I don't get any exceptions or errors, the sound just doesn't play.
public enum Sounds {
RIFLE("rifle_fire.wav");
private Clip clip;
Sounds(String filename) {
openClip(filename);
}
public synchronized void openClip(String filename) {
try {
URL audioFile = Sounds.class.getResource("/resources/sounds/" + filename);
AudioInputStream audio = AudioSystem.getAudioInputStream(audioFile);
AudioFormat format = audio.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(audio);
} catch (UnsupportedAudioFileException uae) {
System.out.println(uae);
} catch (IOException ioe) {
System.out.println(ioe);
} catch (LineUnavailableException lue) {
System.out.println(lue);
}
}
public synchronized void play() {
if(clip.isRunning()) clip.stop();
clip.setFramePosition(0);
clip.start();
}
public static void init() {
values();
}
}
That is the enumerator I use. It's called from the update() method of my main thread, which is updated every 20 ms. In the update method, I call it like this.
// If the left mouse button is held down, create a new projectile.
if(Globals.buttons[0] && !player.isOnCooldown()) {
createParticle(pAngle);
Sounds.RIFLE.play();
}
Someone suggested I need to close the line after using it, but the sound is only opened once... why would I need to close it? Anyone know what the problem is?
How do we play sound (a music file of any format like .wma, .mp3 ) in a Java desktop application? (not an applet)
I have used the following code (taken from another question on Stack Overflow) but it throws an Exception.
public class playsound {
public static void main(String[] args) {
s s=new s();
s.start();
}
}
class s extends Thread{
public void run(){
try{
InputStream in = new FileInputStream("C:\\Users\\srgf\\Desktop\\s.wma");
AudioStream as = new AudioStream(in); //line 26
AudioPlayer.player.start(as);
}
catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
}
The program when run throws the following Exception:
java.io.IOException: could not create audio stream from input stream
at sun.audio.AudioStream.<init>(AudioStream.java:82)
at s.run(delplaysound.java:26)
Use this library:
http://www.javazoom.net/javalayer/javalayer.html
public void play() {
String song = "http://www.ntonyx.com/mp3files/Morning_Flower.mp3";
Player mp3player = null;
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new URL(song).openStream());
mp3player = new Player(in);
mp3player.play();
} catch (MalformedURLException ex) {
} catch (IOException e) {
} catch (JavaLayerException e) {
} catch (NullPointerException ex) {
}
}
Hope that helps everyone with a similar question :-)
Hmmm. This might look like advertisement for my stuff, but you could use my API here:
https://github.com/s4ke/HotSound
playback is quite easy with this one.
Alternative: use Java Clips (prebuffering)
... code ...
// specify the sound to play
File soundFile = new File("pathToYouFile");
//this does the conversion stuff for you if you have the correct SPIs installed
AudioInputStream inputStream =
getSupportedAudioInputStreamFromInputStream(new FileInputStream(soundFile));
// load the sound into memory (a Clip)
DataLine.Info info = new DataLine.Info(Clip.class, inputStream.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
// due to bug in Java Sound, explicitly exit the VM when
// the sound has stopped.
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
event.getLine().close();
System.exit(0);
}
}
});
// play the sound clip
clip.start();
... code ...
Then you need this method:
public static AudioInputStream getSupportedAudioInputStreamFromInputStream(InputStream pInputStream) throws UnsupportedAudioFileException,
IOException {
AudioInputStream sourceAudioInputStream = AudioSystem
.getAudioInputStream(pInputStream);
AudioInputStream ret = sourceAudioInputStream;
AudioFormat sourceAudioFormat = sourceAudioInputStream.getFormat();
DataLine.Info supportInfo = new DataLine.Info(SourceDataLine.class,
sourceAudioFormat,
AudioSystem.NOT_SPECIFIED);
boolean directSupport = AudioSystem.isLineSupported(supportInfo);
if(!directSupport) {
float sampleRate = sourceAudioFormat.getSampleRate();
int channels = sourceAudioFormat.getChannels();
AudioFormat newFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate,
16,
channels,
channels * 2,
sampleRate,
false);
AudioInputStream convertedAudioInputStream = AudioSystem
.getAudioInputStream(newFormat, sourceAudioInputStream);
sourceAudioFormat = newFormat;
ret = convertedAudioInputStream;
}
return ret;
}
Source for the Clip example (with little changes by me): http://www.java2s.com/Code/Java/Development-Class/AnexampleofloadingandplayingasoundusingaClip.htm
SPIs are added via adding their .jars to the classpath
for mp3 these are:
http://www.javazoom.net/mp3spi/mp3spi.html
http://www.javazoom.net/javalayer/javalayer.html
http://www.tritonus.org/plugins.html (tritonus_share.jar)
Using JavaFX (which is bundled with your JDK) is pretty simple.
You will need the following imports:
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import java.nio.file.Paths;
Steps:
Initialize JavaFX:
new JFXPanel();
Create a Media (sound):
Media media = new Media(Paths.get(filename).toUri().toString());
Create a MediaPlayer to play the sound:
MediaPlayer player = new MediaPlayer(media);
And play the Media:
player.play();
You can set the start/stop times as well with MediaPlayer.setStartTime() and MediaPlayer.setStopTime():
player.setStartTime(new Duration(Duration.ZERO)); // Start at the beginning of the sound file
player.setStopTime(1000); // Stop one second (1000 milliseconds) into the playback
Or, you can stop playing with MediaPlayer.stop().
A sample function to play audio:
public static void playAudio(String name, double startMillis, double stopMillis) {
Media media = new Media(Paths.get(name).toUri().toString());
MediaPlayer player = new MediaPlayer(media);
player.setStartTime(new Duration(startMillis));
player.setStopTime(new Duration(stopMillis));
player.play();
}
More info can be found at the JavaFX javadoc.
I am trying to play a sound in Java.
So far it is going well, thank you, but I have a problem understanding how does this work.
I wrote a function that does the playback:
private static void PlaySound(String path) {
try {
final File SoundFile = new File(path);
AudioInputStream Sound = AudioSystem.getAudioInputStream(SoundFile);
DataLine.Info info = new DataLine.Info(Clip.class, Sound.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(Sound);
clip.addLineListener(new LineListener() {
public void update (LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
event.getLine().close();
System.out.printf("Playback ended!");
System.exit(0);
}
}
});
System.out.printf("This sound is %f seconds long.", (clip.getMicrosecondLength() / 1000.0d));
clip.start();
} catch (Exception e) {
ErrorHandler(e);
}
}
Now this function works almost fine: when the sound has ended, it calls the event.getLine().close(); function, but it is stuck in an "infinite loop" (not sure if it is) and nothing after that statement gets executed, and the program runs until I kill it manually.
If I change the line
if (event.getType() == LineEvent.Type.STOP) {
to
if (event.getType() == LineEvent.Type.CLOSE) {
then the sound plays, and the program exits correctly, but still none of the statement after the event.getLine().close(); are executed.
The question is: is this the intended behavior of event.getLine().close(), or I am doing something wrong?
Solution:
The LineListener is actually based on an outdated fact, that Java Sound has a bug in it, and we need to exit explicitly from the vm. Without the listener, the code just works fine.
See if it's raising an exception:
public void update (LineEvent event) {
if (event.getType().equals(LineEvent.Type.STOP)) {
try {
event.getLine().close();
} catch (Throwable t) {
t.printStackTrace();
}
System.out.printf("Playback ended!");
}
}