2016-10-07 5 views
1

Javaのサウンド再生はエラーではじまりますが、サウンドは再生されません。Javaサウンドコントロールが動作しない

私は、Webを検索したが、それはまだDが動作しません:

あなたは私が私の問題+が修正を理解する助けてくださいすることができますか?

詳細、コード、ダンプ、出力、データが必要な場合は、私に知らせてください。

Sound.java:

package com.itaysharon.questematic; 

import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 
import javax.sound.sampled.LineUnavailableException; 

import com.itaysharon.questematic.enums.SoundOptions; 

public class Sound { 

public static Thread dj; 

public static synchronized void playSound(final String url, SoundOptions mode) { 
    dj = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      try { 
       AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("assets" + File.separator + url)); 
       AudioSystem.getClip().open(inputStream); 
       AudioSystem.getClip().setFramePosition(0); 
       switch(mode) { 
        case Stop: 
         AudioSystem.getClip().stop(); 
         break; 
        case Play: 
         AudioSystem.getClip().start(); 
         break; 
        case Loop: 
         AudioSystem.getClip().loop(Clip.LOOP_CONTINUOUSLY); 
         break; 
       } 
      } catch (Exception e) { 
       System.err.println(e.getMessage()); 
      } 
     } 
    }); 
    if (mode != SoundOptions.Stop) { 
     dj.start(); 
    } else { 
     try { 
      AudioSystem.getClip().stop(); 
      AudioSystem.getClip().close(); 
      dj.interrupt(); 
     } catch (LineUnavailableException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 
} 

SoundOptions.java:

package com.itaysharon.questematic.enums; 

public enum SoundOptions { 
    Play, Loop, Stop; 
} 
+0

エラーメッセージ –

+0

を共有してください可能性がエラーメッセージはありません、それはちょうどwavファイルを再生しません –

+0

純粋なJavaと特別なライブラリなし –

答えて

2

[OK]をクリックして、コードを確認した後、ここにある非常に小さなものがありました。

私が開始する前に、あなたのコードが以前と同じように一度動作し、後で作業が中断した可能性があります。これは、通常スレッドがうまくプログラミングされていない場合です。

問題は、オーディオファイルが再生される前にスレッドが開始および終了することです。この場合、スレッドはファイルがどれくらいの時間この場合にあるかを知らないためです。

私はあなたのプログラムの振る舞いの完全な論理を持っていないので、私はあなたのコードロジックを維持し、問題を孤立したインスタンスとして解決するいくつかの事柄を追加します。 Btw、私は固定コードをテストして、それは私のマシンの独立したクラスとして素晴らしい作品です。

私は解決策のポイントを述べました。それはスレッドがリスナーによって終了されるまで、オーディオ再生時間を続けることに関するものです。

audioLineClip.addLineListener(new LineListener() { 
    @Override 
    public void update(LineEvent event) { 
     ... listen when audio is ended and close the line. to end the program. 
    } 
}); 

と我々はオーディオが

あなたはどのくらい知っていないとあなたが眠りにどのくらいかわからないので、あなたは理論的に同期させずに一人で Thread.sleep(sometime)を使用していますが、可能性が
synchronized (dj) { 
    while (true) { 
     try { 
      dj.wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

を終了するまで待機している私たちのスレッドを保持オーディオファイルは!

だからあなたの最終的なコードは次のようになり、私はノートで、余分な小さな変更を含む、説明とコードでソリューションを入れている:

import javax.sound.sampled.*; 
import java.io.File; 

/** 
* By Maytham on 07-10-2016. 
*/ 
public class Sound { 

    public static void main(String[] args) { 
     playSound("8k16bitpcm.wav", SoundOptions.Play); 
    } 

    // 1) make it private 
    private static Thread dj; 

    // 2) make it private and 3) SoundOptions should be final 
    private static synchronized void playSound(final String url, final SoundOptions mode) { 
     dj = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        AudioInputStream inputStream = AudioSystem.getAudioInputStream(
          new File("assets" + File.separator + url)); 

        // 4) declare AudioSystem in stead of using AudioSystem repeatedly 
        final Clip audioLineClip = (Clip) AudioSystem.getLine(
          new Line.Info(Clip.class)); 
        audioLineClip.open(inputStream); 
        audioLineClip.setFramePosition(0); 

        // 5) our line listener checks when audio is ended and stops the line 
        //this is full example, but you manipulated your way 
        audioLineClip.addLineListener(new LineListener() { 
         @Override 
         public void update(LineEvent event) { 
          LineEvent.Type type = event.getType(); 
          if (type == LineEvent.Type.OPEN) { 
          } else if (type == LineEvent.Type.CLOSE) { 
           System.exit(0); 
          } else if (type == LineEvent.Type.START) { 
          } else if (type == LineEvent.Type.STOP) { 
           audioLineClip.close(); 
          } 
         } 
        }); 

        switch (mode) { 
         case Stop: 
          audioLineClip.stop(); 
          break; 
         case Play: 
          audioLineClip.start(); 
          break; 
         case Loop: 
          audioLineClip.loop(Clip.LOOP_CONTINUOUSLY); 
          break; 
        } 
       } catch (Exception e) { 
        System.err.println(e.getMessage()); 
       } 
      } 
     }); 
     if (mode != SoundOptions.Stop) { 
      dj.start(); 

      // 6) this keep the thread until some line listener change status 
      synchronized (dj) { 
       while (true) { 
        try { 
         dj.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

     } else { 
      dj.interrupt(); 

      // 7) you do not need this it is done by line listener 
      /*try { 
       AudioSystem.getClip().stop(); 
       AudioSystem.getClip().close(); 
       dj.interrupt(); 
      } catch (LineUnavailableException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }*/ 

     } 
    } 
} 
+0

playSoundメソッドをプライベートにする必要がありますか?私は別のクラスからそれを呼び出すよ –

+0

あなたはあなたの構造に応じてそれを保護したり公開したりすることができます –

+0

スレッドは素晴らしいことですが、正しく使用しないと狂ってしまうことがあります。自分のコードをリファクタリングする必要があります:( –

関連する問題