2017-12-08 5 views
0

私はオーディオビジュアライザをプログラミングしています。表示するデータを音楽自体に同期させるには、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が返されます。

ご意見はお寄せいただければ幸いです。私はこれまで同様の質問をしてきましたが、この編集によって問題はもう少し明確かつ短くなりました。

編集:この例を実行するのに必要なすべてのコードが含まれている必要があります。

+0

MCVEが役立つ可能性があります。 –

答えて

1

私はあなたの質問を理解したかどうかはわかりませんが、私はあなたにいくつかのことを説明しようとします。

クラスClipがあります.300msから1000msのランダムな時間にクリップの1秒間を再生し、他のスレッドから取得したい変数currentLengthを設定します。

public class Clip implements Runnable { 

    private int clipLength; 

    private volatile int currentLength; 

    public Clip(int clipLength) { 
     this.clipLength = clipLength; 
    } 

    public void run() { 

     while (currentLength <= clipLength) { 
      try { 
       currentLength += 1; 
       Thread.sleep(ThreadLocalRandom.current().nextInt(300, 1000 + 1)); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    public int getCurrentLength() { 
     return currentLength; 
    } 

    public void setCurrentLength(int currentLength) { 
     this.currentLength = currentLength; 
    } 

} 

はまた、あなたがクラスPlayerとそれがないであるが、クリップオブジェクトを取り、いくつかの時間後に、それはそれの現在の長さを要求しているとします。

public class Player implements Runnable { 

    private Clip clip; 

    public Player(Clip clip) { 
     this.clip = clip; 
    } 

    public void run() { 
     try { 
      Thread.sleep(1000); 
      System.out.println(clip.getCurrentLength()); 
      Thread.sleep(2000); 
      System.out.println(clip.getCurrentLength()); 
      Thread.sleep(1000); 
      System.out.println(clip.getCurrentLength()); 
      Thread.sleep(3000); 
      System.out.println(clip.getCurrentLength()); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

さらに、私たちは、Clipオブジェクトを作成し、それを実行可能クラスに渡すプログラムの開始を含むMainクラスを持っています。

public class Main { 
    public static void main(String[] args) { 
     Clip clip = new Clip(60); 
     Thread thread = new Thread(clip); 
     thread.start(); 
     Thread threadPlayer = new Thread(new Player(clip)); 
     threadPlayer.start(); 

    } 

} 

私は約atomic access and volatile keywordともさえないという異なるアプローチを使用して解決Java memory model.

+0

ありがとう!面白い読み物ですが、それは私の質問にはあまり答えませんでした。 – mindoverflow

0

について知る良いです、あなたが読むべき本はあなたが尋ねていると思いますが、前に、あなたのプログラムにそれを実装します質問の一部私はすでに暗号化されたオーディオデータの配列を持っていて、クリップが再生できるAudioInputStreamに変換できます。

関連する問題