java 音频播放不会停止

java audio playing wont stop

好的,我有这个问题:我的音频开始正常播放,但即使在 "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 );

        }
    }

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

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

相反,您需要停止之前启动的 Clip 实例。

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

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();
    }
}

"Why?" 你问,因为现在我可以创建代表特定声音的 subclass 并加载它们,而不需要关心或记住音频的来源是什么,例如.. .

public class MainTheme extends Audio {

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

}

现在,我可以在需要时轻松创建 "main theme" 音频,而不必关心它的来源是什么

这也意味着我可以将 MainTheme 传递给程序的其他部分,这些部分需要 Audio 的实例并简单地卸载管理

然后你只需要根据需要创建一个 class 和 start/stop 的实例,例如...

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);
        }
    }
}