2014-12-03 3 views
3

Я разрабатываю простое приложение таймера, но у меня есть некоторые проблемы с воспроизведением звука.Как играть в звук в java?

Вот мой код

public class Timer { 

    private static int time = 0; 

    public static void main(String[] args) { 
     Scanner scanner = new Scanner(System.in); 

     System.out.println("Type the values"); 
     System.out.print("Hours : "); 
     int hours = scanner.nextInt(); 
     System.out.print("Minutes : "); 
     int minutes = scanner.nextInt(); 
     System.out.print("Seconds : "); 
     int seconds = scanner.nextInt(); 

     time = hours * 3600 + minutes * 60 + seconds; 

     new Thread() { 
      @Override 
      public void run() { 
       try { 
        while (time != 0) { 
         time--; 
         sleep(1000); 
        } 
        System.out.println("Time elapsed"); 
        URL url = Timer.class.getResource("Timer.wav"); 
        AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
        Clip clip = AudioSystem.getClip(); 
        clip.open(audioIn); 
        clip.start(); 
       } catch (InterruptedException | UnsupportedAudioFileException | IOException | LineUnavailableException e) { 
        e.printStackTrace(); 
       } 
      } 
     }.start(); 

     System.out.println("Timer started"); 

    } 
} 

И вот моя структура проекта. enter image description here Теперь проблема в том, что приложение не дает мне исключения, хотя оно не воспроизводит звук. Что не так?

+0

Попробуйте добавить 'clip.setFramePosition (0);' 'перед clip.start();'? Но убедитесь, что вы входите в небольшое количество, чтобы на самом деле спать в течение небольшого промежутка времени. – BitNinja

+0

catch (исключение e), а не список исключений, которые вы сейчас ловите. Ваш код может вызывать любой длинный список классов исключений, включая NullPointerException, и это может происходить беззвучно. –

+0

Пробовали ли вы какие-либо из приведенных ниже предложений? Помогло ли это? – Elist

ответ

3

Это действительно многопоточная проблема.

Проблема в том, что вы запускаете клип, но затем завершаете свою программу, не давая ей возможность сыграть до конца. Метод Clip.start() не является блокировкой, что означает, что он не ждет, а скорее запускает новый поток демона для воспроизведения звука, поток демона, который убивается, когда программа выходит из метода main.

Вот пример кода из моего other answer, для воспроизведения аудиофайла с использованием Clip. Обратите внимание, как я рассчитываю продолжительность звука, а затем sleep(), чтобы он мог играть.

import java.io.File; 
import java.io.IOException; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.UnsupportedAudioFileException; 

public class PlaySound { 
    private static boolean tryToInterruptSound = false; 
    private static long mainTimeOut = 3000; 
    private static long startTime = System.currentTimeMillis(); 

    public static synchronized Thread playSound(final File file) { 

     Thread soundThread = new Thread() { 
      @Override 
      public void run() { 
       try{ 
        Clip clip = null; 
        AudioInputStream inputStream = null; 
        clip = AudioSystem.getClip(); 
        inputStream = AudioSystem.getAudioInputStream(file); 
        AudioFormat format = inputStream.getFormat(); 
        long audioFileLength = file.length(); 
        int frameSize = format.getFrameSize(); 
        float frameRate = format.getFrameRate(); 
        long durationInMiliSeconds = 
          (long) (((float)audioFileLength/(frameSize * frameRate)) * 1000); 

        clip.open(inputStream); 
        clip.start(); 
        System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound started playing!"); 
        Thread.sleep(durationInMiliSeconds); 
        while (true) { 
         if (!clip.isActive()) { 
          System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound got to it's end!"); 
          break; 
         } 
         long fPos = (long)(clip.getMicrosecondPosition()/1000); 
         long left = durationInMiliSeconds - fPos; 
         System.out.println("" + (System.currentTimeMillis() - startTime) + ": time left: " + left); 
         if (left > 0) Thread.sleep(left); 
        } 
        clip.stop(); 
        System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound stoped"); 
        clip.close(); 
        inputStream.close(); 
       } catch (LineUnavailableException e) { 
        e.printStackTrace(); 
       } catch (UnsupportedAudioFileException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (InterruptedException e) { 
        System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound interrupted while playing."); 
       } 
      } 
     }; 
     soundThread.setDaemon(true); 
     soundThread.start(); 
     return soundThread; 
    } 

    public static void main(String[] args) { 
     Thread soundThread = playSound(new File("C:\\Booboo.wav")); 
     System.out.println("" + (System.currentTimeMillis() - startTime) + ": playSound returned, keep running the code"); 
     try { 
      Thread.sleep(mainTimeOut); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     if (tryToInterruptSound) { 
      try { 
       soundThread.interrupt(); 
       Thread.sleep(1); 
       // Sleep in order to let the interruption handling end before 
       // exiting the program (else the interruption could be handled 
       // after the main thread ends!). 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     System.out.println("" + (System.currentTimeMillis() - startTime) + ": End of main thread; exiting program " + 
       (soundThread.isAlive() ? "killing the sound deamon thread" : "")); 
    } 
} 
0

Редактировать: Это может помочь, если я прочитал весь код перед отправкой ответа lol. Итак, ваш class.getResource («Timer.wav») должен быть class.getResource («resources/Timer.wav»). Я предполагаю, что ресурсы - это папка в вашей структуре класса. Также, если вы используете getResourceAsStream вместо getResource, вы можете пропустить URL-адрес.

+0

Точка в том, что мне нужно подождать, пока не начнется воспроизведение звука, а затем выйти из приложения – Carmine

+0

Действительно ли звук воспроизводится? Я имею в виду, если вы не выходите, звучит ли игра? –

+0

Да, он играет. вы можете увидеть мое решение ниже, и оно работает – Carmine

0

Вы должны проверить, чтобы увидеть, если ресурс был фактически получен успешно:

URL url = Timer.class.getResource("Timer.wav"); 
if (url == null) 
{ 
    System.out.println("wav file resource not found!"); 
    return; 
} 
// continue on 

Кроме того, добавить неперехваченное обработчик исключений в программе, чтобы увидеть, если какие-либо исключения спасаясь весь путь к вершине ваша программа:

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() 
{ 
    public void uncaughtException(Thread t, Throwable e) 
    { 
     String msg = "DefaultUncaughtExceptionHandler thread[" + t.getName() + "]"; 
     System.out.println(msg); 
     e.printStackTrace(System.out); 
     System.err.println(msg); 
     e.printStackTrace(System.err); 
    } 
}); 
1

Проблема заключалась в том, что приложение вышло перед тем, как клип начал играть. Итак, я заменил свой игровой блок новым.

   URL url = Timer.class.getResource("Timer.wav"); 
       AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
       AudioFormat format = audioIn.getFormat(); 
       Clip clip = AudioSystem.getClip(); 
       clip.open(audioIn); 
       clip.start(); 
       long frames = audioIn.getFrameLength(); 
       double durationInSeconds = (frames + 0.0)/format.getFrameRate(); 
       sleep((long) durationInSeconds * 1000); 

Теперь она ждет, пока клип игр и отделки, и только тогда приложение завершает его работу

Смежные вопросы