java – 使用Clip对象播放多个声音片段
发布时间:2020-12-15 07:37:03 所属栏目:Java 来源:网络整理
导读:我正在开发一个包含大量JButton对象的程序,我希望每个对象都有自己的.wav文件.此外,我希望声音以某种方式工作,使得它们可以与其他按钮的声音重叠,但它不能与自身重叠(在播放声音时单击按钮将重新启动声音). 我尝试使用一个Clip对象,但我无法完成上面所说的内
我正在开发一个包含大量JButton对象的程序,我希望每个对象都有自己的.wav文件.此外,我希望声音以某种方式工作,使得它们可以与其他按钮的声音重叠,但它不能与自身重叠(在播放声音时单击按钮将重新启动声音).
我尝试使用一个Clip对象,但我无法完成上面所说的内容.结果,我使用每个按钮声明一个新的Clip对象,但我觉得这对我的问题来说是一个相当低效的解决方案. 我怎样才能以最有效的方式完成我在第一段中所说的内容? 解决方法
有几种方法可以实现这一点,但基本思路是,您希望将LineListener注册到Clip并监视LineEvent.Type.STOP事件并重新启用该按钮
例如.这将查找给定目录中的所有.wav文件,并为每个文件创建一个按钮.单击时,按钮(或更重要的是,基础操作)被禁用并播放音频.当它停止时,重新启用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(); } } } } nb:我尝试使用Clip#drain(在后台线程中),但它只适用于第一个剪辑,后续剪辑基本上跳过了方法,因此我选择了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(),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,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; } } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |