2017-03-05 136 views
0

没关系,我有这样的问题:我的声音开始正常播放,但即使它不会停止,“clip.stop()”或“clip.close()” ......你有什么想法该怎么做才能阻止它? (我甚至可以接受甚至静音,我真的很绝望)java的音频播放不会停止

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

     } 
    } 
+0

当你尝试调用'stop',你调用'在'Clip'这是不是在玩stop',您需要使用相同的参考在'Clip'你叫'上 – MadProgrammer

回答

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的实例并简单地卸载管理

然后你只需要创建一个类的实例和启动/ STO p将其按要求,例如...

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

感谢stop',这对我帮助很大,我只是有一些麻烦与子说:“公众型MainTheme必须在它自己的文件中定义 \t不能引用实例方法,而明确地调用构造函数“...你知道如何解决这个问题吗? –

+0

你复制这是MainTheme类包括 – MadProgrammer

+0

肯定,并把它的权利低于去年音频类“}”(我真的很傻程序员顺便说一句,很抱歉:')) –