I am trying to play mp3's in my java application. The user has the ability to click a button and change the sound.
The sound and switching works...however when a user tries to switch sounds, the new song begins playing over the old one for about a second, before the old one stops playing. I am trying use threads to handle everything.
My MP3 class:
import java.applet.*;
import javazoom.jl.player.Player;
import java.io.*;
import java.io.FileInputStream;
import java.net.*;
public class mp3 extends Thread implements Runnable{
private Player sound;
private InputStream path;
public mp3(String file_name) {
path = mp3.class.getClassLoader().getResourceAsStream(file_name);
}
public void run(){
try {
Player sound=new Player(path);
sound.play();
} catch(Exception e) {System.out.println(e);}
}
}
And this is how I attempt to run the code in my main game. The MP3 object is called song.
When the application initializes, the following code is run:
song = new mp3("default.mp3");
song.start();
somebody tries to change it, the following code is run:
song.stop();
song = new mp3(t+".mp3");
song.start();
Where t is a parameter of the file name.
I'm pretty sure the problem relies in the run function of the MP3 object. I am completely new to threading so I would appreciate some help.
Again, the delay is about 1 second from the time "stop" is called and the time it actually stops playing. So maybe throw a wait in there somewhere?
Thanks!
EDIT: I am using code based off of here now:
I have created a play and close function defined as follows:
public void close() { if (player != null) player.close(); }
// play the MP3 file to the sound card
public void play() {
try {
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
player = new Player(bis);
} catch (Exception e) {
System.out.println("Problem playing file " + filename);
System.out.println(e);
}
// run in new thread to play in background
new Thread() {
public void run() {
try { player.play(); }
catch (Exception e) { System.out.println(e); }
}
}.start();
My problem is with the close function...the player object is always null and the close function does not execute...even though the play function initializes it. Why is it null?
Edit:
In your edit, if multiple threads are accessing the player
field then it should be made volatile
. Without seeing how player
is defined, it's hard to guess at the problem otherwise.
I think that you will need to make sure that the Player
has completed the previous mp3 before you start the next. Looking the javadocs for Player
I see:
`player.isComplete()`
To quote:
Returns true if all available MPEG audio frames have been decoded, or false otherwise
If you want to stop the previous audio when the new sound starts you should use close()
on the older player.
Closes this player. Any audio currently playing is stopped immediately
Sounds to me that you need to close the current running Player
object (if any) and start a new Player
object to play the new sound. If you are doing this in multiple threads then you will need to do something like:
final Object lock
object Player
object (if any) has completed in a loop with sleep
close()
the current Player
object and create a new Player
if you want to kill the current sound play()
the next mp3, As far as I know, the play()
method does not wait for the sound to be played but returns immediately after loading the sound into the audio buffers. I'm not sure what happens if the audio file is large though.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.