私はオーディオビジュアライザをプログラミングしています。表示するデータを音楽自体に同期させるには、clip.getMicrosecondPosition()
/player.getPosition()
を呼び出して、オーディオファイル内のクリップ/プレーヤーの現在の位置を取得する必要があります。これはクリップのためにうまくいきます。問題は、ファイルを最後まで再生するまで、player.play()
を呼び出すと、現在のスレッドですべての実行が停止するため、別のスレッドでプレーヤーオブジェクトを定義する必要があることです。 Player
は、MP3SPIライブラリ(javazoom.jl.player.Player
)のクラスです。別のスレッドで定義されたクラスの変数を返します
コード:
public class AudioTools implements Runnable {
public File file;
public boolean isMP3 = false;
public Player player;
public Clip clip;
public AudioTools(File file) {
this.file = file;
determineFilyType();
}
private void determineFileType() {
if (file.getAbsolutePath().endsWith(".mp3")) {
this.isMP3 = true;
} else if (file.getAbsolutePath().endsWith(".wav")) {
this.isMP3 = false;
} else {
System.err.println("Invalid File Type!");
System.exit(0);
}
}
public void play() {
if (isMP3) {
Thread t = new Thread(this);
t.start(); // play MP3 using Player class
} else {
playWav(file); // play WAV using Clip class
}
}
protected void playMP3(File file){
try {
player = new Player(new FileInputStream(file));
player.play();
} catch (Exception e) {
System.out.println("Invalid MP3 File!");
e.printStackTrace();
System.exit(0);
}
}
@Override
public void run() {
playMP3(file);
}
private void playWav(File file) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(file);
DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
clip = (Clip) AudioSystem.getLine(dataInfo);
clip.open(ais);
clip.start();
} catch (Exception e) {
e.printStackTrace();
System.err.println("Invalid .wav file!");
System.exit(0);
}
}
}
メインクラス:
public static void main(String[] args) {
File file = new File(/*PATH_TO_FILE_HERE*/);
AudioTools at = new AudioTools(file);
at.play();
// at.clip.getMicrosecondPosition() works here if loaded file is .wav.
// at.player.getPosition() returns null if loaded file is .mp3.
}
メインクラスから、私はプレイヤーの現在位置を取得できるようにしたいと思います。現在、これを試行するとnullが返されます。
ご意見はお寄せいただければ幸いです。私はこれまで同様の質問をしてきましたが、この編集によって問題はもう少し明確かつ短くなりました。
編集:この例を実行するのに必要なすべてのコードが含まれている必要があります。
MCVEが役立つ可能性があります。 –