2013-03-27 9 views
2

Я работаю в течение нескольких дней, чтобы попытаться исправить мою программу. Он успешно воспроизводит песню, но не может воспроизводить песню.Звук не воспроизводится дважды

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

Вот пример, демонстрирующий сломанный код (не будет играть песню еще раз):

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

public class test{ 
    static Clip musicplayer; 
    static AudioInputStream currentSong; 

    public static void main(String[] args){ 
     try{ 
      musicplayer = AudioSystem.getClip(); 
      AudioInputStream ais = AudioSystem.getAudioInputStream(new test().getClass().getResource("test.wav")); 
      playMusic(ais); 
      System.out.println("Playing Music"); 
      Thread.sleep(4000); 
      stopMusic(); 
      System.out.println("Stopping Music"); 
      Thread.sleep(3000); 
      playMusic(ais); 
      System.out.println("Playing Music for the Second time"); 
      Thread.sleep(5000); 
      System.out.println("Finished Program"); 
     }catch(Exception ex){ex.printStackTrace();} 
    } 

    public static void playMusic(AudioInputStream music){ 
     if(music == null) 
      return; 

     if(currentSong != null){ 
      if(currentSong.equals(music)) 
       return; 
     } 

     currentSong = music; 

     try { 
       musicplayer.setFramePosition(0); 
       musicplayer.stop(); 
       musicplayer.open(currentSong);  
     } catch (LineUnavailableException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     musicplayer.loop(Clip.LOOP_CONTINUOUSLY); 
    } 

    public static void stopMusic(){ 
     musicplayer.close();    
    } 
} 

Если добавить еще один AudioInputStream в, и играть, что, как моя вторая песня, она отлично работает.

ответ

2

У вас есть две проблемы в этой части кода

текущая песня никогда не сбрасываются, так что если вы пытаетесь играть один и тот же поток дважды он будет просто прервать.

... 
    if(currentSong != null){ 
     if(currentSong.equals(music)) 
      return; 
    } 

... 

Очистить.

public static void stopMusic(){ 
    musicplayer.close();    
    currentSong = null; // we do not have a current song anymore. 
} 

Другая проблема заключается в том, что вы не перерегистрируете входной поток. Самый простой способ - просто перезагрузить его. Потоки - это не массив, который вы можете дать чему-то, и он начнет волшебно начинаться с самого начала. Любой доступ к потоку может только получить то, что будет дальше, если вы дадите что-то Stream, где следующий бит - это конец, тогда ничего не произойдет.

AudioInputStream ais = AudioSystem.getAudioInputStream(new test().getClass().getResource("test.wav")); 
    playMusic(ais); 

    ais = AudioSystem.getAudioInputStream(new test().getClass().getResource("test.wav")); 
    playMusic(ais); 

одна вещь, чтобы быть в курсе, что AudioInputStream не реализует равняется так

AudioSystem.getAudioInputStream(new test().getClass().getResource("test.wav")).equals(AudioSystem.getAudioInputStream(new test().getClass().getResource("test.wav"))) 

будет оценивать ложь.

+0

Нет, все еще не работает. Поле currentSong состоит в том, что оно будет воспроизводиться только при выборе другой песни или когда песня будет остановлена. вы можете проверить метод, распечатав каждую переменную, чтобы увидеть, к чему идет поток. – user2097804

+0

Реальное решение заключалось в том, чтобы обойти его, перезагружая звук каждый раз, когда он хотел быть воспроизведенным ... :(Я буду принимать ваш ответ, поскольку установка currentSong на null может немного помочь решению – user2097804

+0

Ответ BevynQ верен не для «обходной путь», который, по вашему мнению, вы сделали. Вы не обновляете 'currentSong' или' music'. Они строго одни и те же. –

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