2012-04-17 20 views
1

私は自分のJavaアプリケーションでmp3を再生しようとしています。ユーザーはボタンをクリックしてサウンドを変更することができます。Javaスレッドが遅延で終了する

サウンドと切り替えの作業...しかし、ユーザーがサウンドを切り替えようとすると、古い曲が再生を停止する前に、新しい曲が古いものより約1秒間再生されます。私はすべてを処理するスレッドを使用しようとしています。

マイ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(); 

誰かがそれを変更しようとすると、次のコードが実行される:tは、ファイル名のパラメータである

song.stop(); 
song = new mp3(t+".mp3"); 
song.start(); 

を。

私はこの問題がMP3オブジェクトの実行機能に依存していると確信しています。私はスレッドに完全に新しいので、私はいくつかの助けに感謝します。

"stop"が呼び出されてから実際に再生が停止するまでの遅延時間は約1秒です。だからどこかで待っているかもしれない?

ありがとうございます!

EDIT:私は今ここでのオフに基づいてコードを使用しています:

http://introcs.cs.princeton.edu/java/faq/mp3/MP3.java.html

を次のように私は演劇を作成しているし、近い関数が定義:

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(); 

私の問題はclose関数です...プレーヤーオブジェクトは常にnullで、close関数は実行されません。プレイ関数はそれを初期化しますが。なぜそれはnullですか?

+1

'Thread.stop()'は廃止されたメソッドであり、使用しないでください。 – Gray

+0

['Clip'](http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/Clip.html)や[' BigClip'](http: //stackoverflow.com/a/9470886/418556)。 –

+0

スレッドを拡張するか、Runnableを実装します。両方を行う必要はありません。スレッドをシャットダウンするのは、サウンドをすぐに止める正しい方法ではないでしょう。 JavazoomのPlayerが提供するいくつかのメソッドがあるはずです。存在しなければ、それはそのオブジェクトの欠陥です。また、Playerの各インスタンスは、おそらく再利用を試みるのではなく、独自のスレッド内に存在する必要があります。 –

答えて

1

編集:複数のスレッドがplayerフィールドにアクセスしている場合は、あなたの編集で

、それはvolatileなされるべきです。 playerがどのように定義されているかを見ることなく、そうでなければ問題を推測するのは難しいです。


私はあなたが次を開始する前にPlayerが前のmp3を完了したことを確認する必要があると思います。

`player.isComplete()` 

を引用すると::探しjavadocs for Playerは私が見るすべての利用可能なMPEGオーディオフレームが復号された場合

trueを返し、そうでない場合はfalse

前を停止する場合新しいサウンドが開始されたら、古いプレーヤーでclose()を使用する必要があります。

このプレーヤーを終了します。現在再生中は、すぐに

を停止している任意のオーディオを使用すると、現在実行中のPlayerオブジェクト(もしあれば)を閉じ、新しいサウンドを再生するには、新しいPlayerオブジェクトを起動する必要があることを私にね。

  1. あなたは最後まで現在のサウンドをしたい場合は、現在のPlayerオブジェクト(もしあれば)が完了したチェックいくつかfinal Object lockオブジェクト
  2. をロック:あなたが複数のスレッドでこれをやっているなら、あなたのような何かを行う必要がありますあなたが現在のサウンド
  3. コールplay()次のmp3を殺したい場合sleep
  4. close()現在Player対象としてループで、新しいPlayerを作成
  5. ロックオブジェクトのロックを解除します。

私が知る限り、play()メソッドは、サウンドが再生されるのを待つのではなく、音声をオーディオバッファにロードした直後に戻ります。私はオーディオファイルが大きい場合はどうなるのか分かりません。

+0

お返事ありがとうございます。私はサウンドを変更する必要があるときにsound.closeを呼び出す関数を作成しようとしました。ただし、サウンドファイルを変更した後は、そのサウンドが再び使用されないように見えます。私はnullポインタの例外を取得します。 close()は何らかのデストラクタですか? –

+0

それは@Katherineかもしれません。そうですね、ドキュメントを見て、新しい 'Player'オブジェクトを作成しなければならないかもしれません。私はそれを補うために私の答えを少し変えました。 – Gray

関連する問題