我正在尝试在我的java应用程序中播放mp3。用户可以单击按钮并更改声音。
声音和切换工作......但是当用户试图切换声音时,新歌开始播放旧歌曲大约一秒钟,然后旧歌曲停止播放。我正在尝试使用线程来处理所有事情。
我的MP3课程:
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);}
}
}
这就是我尝试在主游戏中运行代码的方式。 MP3对象称为歌曲。
当应用程序初始化时,运行以下代码:
song = new mp3("default.mp3");
song.start();
有人试图更改它,运行以下代码:
song.stop();
song = new mp3(t+".mp3");
song.start();
其中t是文件名的参数。
我很确定问题依赖于MP3对象的运行功能。我对线程是全新的,所以我会感激一些帮助。
同样,从“停止”被调用的时间到实际停止播放的时间,延迟约为1秒。那么也许在那里等一下?
谢谢!
编辑:我现在正在使用此处的代码:
我创建了一个play和close函数,定义如下:
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();
我的问题是关闭函数...播放器对象总是为null而close函数不执行...即使play函数初始化它。为什么它是空的?
答案 0 :(得分:1)
修改强>
在您的编辑中,如果多个线程正在访问player
字段,那么应该将其设为volatile
。在没有看到如何定义player
的情况下,很难再猜出这个问题。
我认为您需要确保Player
在开始下一个之前已经完成了之前的mp3。看javadocs for Player
我看到了:
`player.isComplete()`
引用:
如果所有可用的MPEG音频帧都已解码,则返回true,否则返回
如果您想在新声音开始时停止上一个音频,则应在旧播放器上使用close()
。
关闭此播放器。当前播放的任何音频都会立即停止
听起来你需要关闭当前正在运行的Player
对象(如果有的话)并启动一个新的Player
对象来播放新声音。如果您在多个线程中执行此操作,则需要执行以下操作:
final Object lock
对象Player
对象(如果有)已在sleep
close()
当前Player
对象,如果您想杀死当前声音,请创建一个新Player
play()
下一个mp3,据我所知,play()
方法不会等待播放声音,而是在将声音加载到音频缓冲区后立即返回。我不确定如果音频文件很大会发生什么。