当前位置: 首页 > 知识库问答 >
问题:

使用Clip对象播放多个声音剪辑

越季萌
2023-03-14

我正在开发一个具有许多JButton对象的程序,我希望每个对象都对应于自己的.wav文件。另外,我希望声音的工作方式是,它们可以与其他按钮的声音重叠,但它不能与自身重叠(在播放声音时单击按钮将重新启动声音)。

我尝试使用单个Clip对象,但我无法完成上面所述的内容。因此,我不得不为每个按钮声明一个新的Clip对象,但我觉得这对我的问题来说是一个相当低效的解决方案。

我怎样才能以最有效的方式完成我在第一段中陈述的内容?

共有2个答案

管杜吟
2023-03-14

每个按钮一个剪辑应该可以。当用户单击按钮时,运行此命令以重新启动剪辑:

sound.stop();
sound.setFramePosition(0);// set the location to the start of the file
sound.play();// restart your sound
吴星汉
2023-03-14

有几种方法可以实现这一点,但基本思想是,您希望将< code>LineListener注册到< code>Clip并监视< code>LineEvent。键入. STOP事件并重新启用按钮

例如。这将查找给定目录中的所有. wav文件,并为每个文件创建一个按钮。单击时,按钮(或更重要的是,底层的Action)被禁用并播放音频。当它STOPs时,Action(以及扩展按钮)被重新启用。

Sound API可以同时播放多个声音

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
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() {
            File[] musicFiles = new File("a directory somewhere").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.getName().toLowerCase().endsWith(".wav");
                }
            });

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            for (File music : musicFiles) {
                try {
                    JButton btn = new JButton(new AudioAction(music.getName(), music.toURI().toURL()));
                    add(btn, gbc);
                } catch (MalformedURLException ex) {
                    ex.printStackTrace();
                }
            }

        }

    }

    public class AudioAction extends AbstractAction {

        private URL audio;

        public AudioAction(String name, URL audioSource) {
            super(name);
            this.audio = audioSource;
        }

        public URL getAudioSource() {
            return audio;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setEnabled(false);
            try (InputStream is = getAudioSource().openStream()) {
                AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(is);
                Clip play = AudioSystem.getClip();
                play.addLineListener(new LineListener() {
                    @Override
                    public void update(LineEvent event) {
                        System.out.println(event.getFramePosition());
                        if (event.getType().equals(LineEvent.Type.STOP)) {
                            setEnabled(true);
                        }
                    }
                });
                play.open(audioInputStream);
                play.start();
            } catch (IOException | LineUnavailableException | UnsupportedAudioFileException exp) {
                exp.printStackTrace();
            }
        }

    }

}

注意:我尝试使用Clip#rain(在后台线程中),但它仅适用于第一个剪辑,后续剪辑基本上跳过了该方法,因此我选择了LineListener

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileFilter;
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.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.AbstractAction;
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() {
            File[] musicFiles = new File("...").listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.getName().toLowerCase().endsWith(".wav");
                }
            });

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            for (File music : musicFiles) {
                try {
                    JButton btn = new JButton(new AudioAction(music.getName(), music.toURI().toURL()));
                    add(btn, gbc);
                } catch (MalformedURLException exp) {
                    exp.printStackTrace();
                }
            }

        }

    }

    public class AudioAction extends AbstractAction {

        private AudioPlayer player;

        public AudioAction(String name, URL audioSource) {
            super(name);
            player = new AudioPlayer(audioSource);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (player.isPlaying()) {
                player.stop();
            } else {
                try {
                    player.play();
                } catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
                    ex.printStackTrace();
                }
            }
        }

    }

    public class AudioPlayer {

        private Clip clip;
        private URL url;

        public AudioPlayer(URL url) {
            this.url = url;
        }

        public boolean isPlaying() {
            return clip != null && clip.isRunning();
        }

        protected void open() throws IOException, LineUnavailableException, UnsupportedAudioFileException {
            clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(url.openStream()));
        }

        public void play() throws IOException, LineUnavailableException, UnsupportedAudioFileException {
            if (clip == null || !clip.isRunning()) {
                open();
                clip.setFramePosition(0);
                clip.start();
            }
        }

        public void stop() {
            if (clip != null && clip.isRunning()) {
                clip.stop();
                clip.flush();
                dispose();
            }
        }

        public void dispose() {
            try {
                clip.close();
            } finally {
                clip = null;
            }
        }

    }

}
 类似资料:
  • 问题内容: 我正在开发一个包含许多JButton对象的程序,我希望每个对象都对应于其自己的文件。另外,我希望声音能够与其他按钮的声音重叠,但不能与自身重叠(在播放声音时单击按钮将重新启动声音)。 我尝试使用单个Clip对象,但是在完成上述操作时遇到了麻烦。结果,我诉诸于为每个按钮声明一个新的Clip对象,但是我觉得这对我的问题而言是一种效率很低的解决方案。 如何以最有效的方式完成第一段中所述的内容

  • 好吧,标题说明了一切,我尝试使用javax播放wav文件。声音,什么也没有发生。我试过很多不同的文件,但没有任何运气。

  • 问题内容: 在Python中播放声音文件(.wav)的最简单方法是什么?最简单的说,我指的是最独立的平台,并且需要最少的依赖。pygame当然是一个选择,但听起来似乎有些过分。 问题答案: Snack Sound Toolkit可以播放wav,au和mp3文件。

  • 问题内容: 我正在尝试播放声音,但无法正常工作。 编辑1: 仍然行不通。 编辑2 :此代码有效。我的设备处于静音模式。 问题答案: 对您的代码进行了修改: Swift 3和Swift 4.1:

  • 我在javafx上做一个项目有困难。我试图播放声音使用媒体和媒体播放器,但遇到了路径选择的麻烦。我在IntellijIDEA工作。我决定简化工作,并创建了一个类sounds.java创建对象,需要字符串(路径)和方法,将播放和停止声音。就像我可以点击按钮很多次和声音播放一遍又一遍) 这是我的代码(由于使用新方法后出现错误,我将代码放在注释中)( 这里是班级sounds.java

  • 播放(播放音效/播放录音)