java音频播放不会停止

时间:2017-03-05 00:01:13

标签: java swing audio javasound audio-player

好吧,我有这个问题:我的音频开始正常播放,但即使在" clip.stop()"之后它也不会停止。或" clip.close()" ......你知道如何阻止它吗? (我甚至可以接受它静音,我真的很绝望)

public class Main {
     //audio playing
    public static void audio(boolean a) {
        try {

            File file = new File("textures/Main_theme.wav");
            Clip clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(file));

            if(a == true){
            // this loads correctly, but wont stop music
            clip.stop();
           System.out.println(a);
            }
            else{
            clip.start();

            }
        } catch (Exception e) {
            System.err.println("Put the music.wav file in the sound folder if you want to play background music, only optional!");
        }
    }


    private static String arg;

    public static void main(String[] args){

   //picture loading ... ignorable now

    arg = "textures/ccc.gif";
    JFrame f = new JFrame();
    JPanel p = new JPanel();
    JLabel l = new JLabel();
    ImageIcon icon = new ImageIcon(arg);    
    f.setSize(480, 360);
    f.setVisible(true);
    l.setIcon(icon);
    p.add(l);
    f.getContentPane().add(p);
    f.setLocationRelativeTo(null);
    f.setResizable(false);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

     //calling audio method to play sound (works)
    audio(false);

    //should stop music and run another class
    KeyListener action = new KeyListener()
    {
        @Override
        public void keyPressed(KeyEvent e) {
        //trying to stop music
            f.dispose();
            try {

                Menu.menu(args);
                Main.audio(true);

            } catch (IOException e1) {
            //rest of code ... ignorable    
                e1.printStackTrace();
            }

        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

    };
    f.addKeyListener( action );

        }
    }

1 个答案:

答案 0 :(得分:1)

你需要退后一步,想一想你在做什么。

您正在创建Clip并且正在播放它。在将来的某个时刻,您将创建一个新的Clip并尝试停止。这两个Clip有什么联系?他们是如何联系的?答案是,他们不是。将相同的文件加载到单独的Clip并单独播放是非常合理的。

相反,您需要停止之前开始的Clip实例。

因为我很懒,所以我首先将音频功能封装到一个简单的类中。

public class Audio {

    private Clip clip;

    protected Audio() {
    }

    public Audio(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
        this(source.toURI().toURL());
    }

    public Audio(URL source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        this(source.openStream());
    }

    public Audio(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        init(source);
    }

    protected void init(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
        init(source.toURI().toURL());
    }

    protected void init(URL source) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
        init(source.openStream());
    }

    protected void init(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(source));
    }

    public void setRepeats(boolean repeats) {
        clip.loop(repeats ? Clip.LOOP_CONTINUOUSLY : 1);
    }

    public void reset() {
        clip.stop();
        clip.setFramePosition(0);
    }

    public void play() {
        clip.start();
    }

    public void stop() {
        clip.stop();
    }

    public boolean isPlaying() {
        return clip.isActive();
    }
}

“为什么?”你问,因为现在我可以创建代表特定声音的子类并加载它们,而无需关心或记住音频的来源,例如......

public class MainTheme extends Audio {

    public MainTheme() throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
        init(getClass().getResource("textures/Main_theme.wav"));
    }

}

现在,我可以随时轻松创建“主题”音频,而无需关心它的来源是什么

这也意味着我可以将MainTheme传递给程序的其他部分,这些部分期望Audio的实例,并且只需卸载管理

然后你只需要创建一个类的实例并根据需要启动/停止它,例如......

package test;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton btn = new JButton("Click");
            btn.addActionListener(new ActionListener() {

                private Audio audio;

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (audio == null) {
                            audio = new MainTheme();
                        }

                        if (audio.isPlaying()) {
                            audio.stop();
                        } else {
                            audio.play();
                        }
                    } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
                        ex.printStackTrace();
                    }
                }
            });

            add(btn);
        }
    }
}