java音频播放不会停止

标签 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 );

        }
    }

最佳答案

你需要退一步思考一下你在做什么。

您正在创建一个剪辑并正在播放它。在将来的某个时刻,您创建一个新的 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);
        }
    }
}

关于java音频播放不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42602829/

相关文章:

java - 如何在类注册表中正确使用for循环?

java - NetBeans GUI 应用程序在我尝试运行时一直卡住

windows - 如何通过Python静音麦克风

java - 根据深度级别更改 JTree 节点图标

java - 如果窗口大小调整,JLabel 会复制自身

java - J2ME上的音频,不知道哪里错了?

python - 使用python处理音频流(重采样)

java - 在没有线程暂停的情况下执行 ExecutorService 中的任务

java - 无法创建新文件 : The device is not ready

java - 比较两个对象变量时出现问题