Ошибка воспроизведения AudioInputStream

Я хочу создать 2 JMenuItem, которые могут запускать и останавливать фоновый звук.

Вот мой код:

public class MainClass extends JFrame
{
    private AudioInputStream audioInputStream;
    private Clip clip;

    public MainClass(String title)
    {
        try
        {
            audioInputStream = AudioSystem.getAudioInputStream(new File("Background.wav"));
            clip = AudioSystem.getClip();
            clip.loop(Clip.LOOP_CONTINUOUSLY);
            clip.open(audioInputStream);
        }
        catch(Exception e)
        {
            System.out.println("Error with playing sound.");
            e.printStackTrace();
        }
    }
    public void startSound()
    {   
        clip3.start();
        settingSubMenuItem1.setEnabled(false);
        settingSubMenuItem2.setEnabled(true);
    }

    public void stopSound()
    {
        clip3.stop();
        settingSubMenuItem1.setEnabled(true);
        settingSubMenuItem2.setEnabled(false);
    }

    private class MenuItemListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if(e.getSource() == settingSubMenuItem1)
            {
                startSound();
            }
            if(e.getSource() == settingSubMenuItem2)
            {
                stopSound();        
            }
        }
    }
}

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

Но когда я нажимаю settingSubMenuItem2, возникают ошибки, и если снова нажать settingSubMenuItem1, звука больше не будет.

Вот ошибки:

Error with playing sound.
java.lang.IllegalStateException: Clip is already open with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian and frame lengh of 7658

В чем ошибка моей программы?


person Chin    schedule 20.05.2012    source источник
comment
См. также этот предыдущий вопрос.   -  person trashgod    schedule 20.05.2012
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE. Горячая ссылка на pscode.org/media/leftright.wav для зацикливания звука.   -  person Andrew Thompson    schedule 20.05.2012
comment
@trashgod, это мой вопрос......   -  person Chin    schedule 20.05.2012
comment
Точно; вы всегда должны цитировать свои предыдущие вопросы по той же теме: во-первых, чтобы избежать непреднамеренного закрытия как дубликата; во-вторых, чтобы показать отвечающим, как изменилось ваше понимание.   -  person trashgod    schedule 20.05.2012


Ответы (1)


Этот SSCCE здесь является «нулевым результатом», поскольку звук перезапускается (по крайней мере, 3 раза) без каких-либо исключений.

import java.net.URL;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;

public class RestartableLoopSound {

    public static void main(String[] args) throws Exception {
        URL url = new URL(
            "http://pscode.org/media/leftright.wav");
        final Clip clip = AudioSystem.getClip();
        AudioInputStream ais = AudioSystem.
            getAudioInputStream( url );
        clip.open(ais);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JToggleButton b = new JToggleButton("Loop");
                ActionListener listener = new ActionListener() {
                    public void actionPerformed(ActionEvent ae) {
                        if (b.isSelected()) {
                            // loop continuously
                            clip.loop(Clip.LOOP_CONTINUOUSLY);
                        } else {
                            clip.stop();
                        }
                    }
                };
                b.addActionListener(listener);
                JOptionPane.showMessageDialog(null, b);
            }
        });
    }
}
person Andrew Thompson    schedule 20.05.2012
comment
Еще раз спасибо за ваш ответ. Но я думаю, что не буду использовать большую часть вашего кода, потому что я еще не знаю, как использовать SwingUtilities. Тем не менее, я постараюсь изучить ваш код. - person Chin; 20.05.2012
comment
Весь код, использующий компоненты Swing, должен запускать графический интерфейс в EDT. Этого можно легко достичь, используя один из двух классов. EventQueue (AWT) или SwingUtilities (качели). Последний просто выполняет обратный вызов класса AWT. Изучите этот материал, прежде чем создавать другие графические интерфейсы — это важно для стабильного и корректного графического интерфейса. - person Andrew Thompson; 20.05.2012
comment
+1 за invokeLater(). - person trashgod; 20.05.2012
comment
@trashgod Спасибо за редактирование! Не могу поверить, что столько раз смотрел на это «волшебное число», а оно ни разу не выскочило и не рявкнуло на меня. Я отредактировал исходный источник в информации о звуке Java. страницу (откуда это адаптировано) и удалил (теперь совершенно бессмысленный) однострочный комментарий, который предшествует. :) - person Andrew Thompson; 21.05.2012
comment
Превосходно! Ваш часто задаваемые вопросы по javasound представляет собой настоящий пример. - person trashgod; 21.05.2012
comment
@trashgod Спасибо! :) Я чувствую, что нет смысла редактировать WIKI, если вы не собираетесь делать это хорошо. Я использую его в качестве упражнения по извлечению накопленного опыта по предмету. - person Andrew Thompson; 21.05.2012