java音频播放不会停止
好的,我有这个问题:我的音频开始正确播放,但即使在clip.stop或clip.close之后也不会停止。。。你知道怎么阻止它吗?我甚至可以接受静音,我真的很绝望java音频播放不会停止,java,swing,audio,javasound,audio-player,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");
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 );
}
}
你需要退一步想想你在做什么 您正在创建一个剪辑并播放它。在将来的某个时候,创建一个新剪辑并尝试停止。这两个剪辑的共同点是什么?它们是如何连接的?答案是,他们不是。将同一个文件加载到单独的剪辑中并单独播放是非常合理的 相反,您需要停止先前启动的剪辑实例 因为我很懒,所以我首先将音频功能封装到一个简单的类中
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"));
}
}
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);
}
}
}
现在,我可以在需要时轻松创建主主题音频,而不必关心它的来源
这也意味着我可以将主主题传递给程序的其他部分,这些部分需要一个音频实例,并简单地卸载管理
然后您只需要创建一个类的实例,并根据需要启动/停止它,例如
public class MainTheme extends Audio {
public MainTheme() throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
init(getClass().getResource("textures/Main_theme.wav"));
}
}
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);
}
}
}
当你尝试调用stop时,你调用的是一个没有播放的剪辑上的stop,你需要使用与调用stop on Anks相同的引用,这对我帮助很大,我只是对你的子类说:公共类型MainTheme必须在它自己的文件中定义,不能在显式调用构造函数时引用实例方法有一些问题。。。你知道如何解决这个问题吗?你复制了包含的主主题类了吗?是的,把它放在最后一个音频类的正下方。}顺便说一句,我真的是一个愚蠢的程序员,所以很抱歉:'Java更喜欢自己的文件中的类,你可以使用内部类,但要开始,试着每个类使用一个文件好的,酷。。。。这解决了类问题,但它仍然表示:在supergetClass.getResourcetextures/Main_theme.wav处显式调用构造函数时无法引用实例方法;