2016-10-07 204 views
1

我的Java聲音播放以錯誤開始,但不播放聲音。Java聲音控制不起作用

我在網上搜索,但它仍然無法正常工作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檢查你的代碼後,有在這裏和那裏非常小的事情。

在我開始之前,也許你的代碼曾經巧合地工作過一次,之後停止工作,這通常是線程編程不好的時候。

問題是線程在音頻文件獲得播放機會之前開始和結束,因爲線程不知道在這種情況下文件有多長。

由於我沒有關於程序行爲的完整邏輯,我將保留您的代碼邏輯並添加一些解決問題的東西作爲孤立的實例。順便說一句,我已經測試了固定的代碼,它在我的機器中作爲獨立的類運行良好。

我會提到解決方案的關鍵點。這是關於讓線程繼續播放音頻的時間,直到聽衆結束。

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

和我們保持我們的線程等待,直到聲音結束

synchronized (dj) { 
    while (true) { 
     try { 
      dj.wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

理論上你就可以使用Thread.sleep(sometime)單獨使用,而不同步,但因爲你不知道睡了多久,你不知道過了多久音頻文件是!

所以你的最終代碼應該是這樣的,我已經把解決方案中的代碼解釋,包括與筆記額外細微的變化:

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

線程是一件好事,但如果我們不正確地使用它們,我們會變得瘋狂,它是一個世界和藝術它的自我 –