如何停止播放java中的wav剪辑

64jmpszr  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(372)

当按下开始按钮时,我试图停止播放介绍歌曲。我试着用这个代码。请注意,此代码并不包含我的所有代码。gui看起来很好,ActionListener也很好。只有当按下开始按钮时,音乐才不会停止播放。

File introPath = new File("src/BattleshipGUI/423499__soundflakes__epic-heroic-orchestral- 
                                                                      dramatic.wav");
File buttonPressedPath = new File("src/BattleshipGUI/sfx_patcher_button_launch.wav");
static Clip introWAV;

    Menu() {

    super("BattleBoard");

    this.setContentPane(this.panelMain);
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.pack();

    play(introPath); // playing when launching 

    // when the game starts, the sound should stop

    ButtonStartGame.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            super.mouseClicked(e);
            play(buttonPressedPath);

            try {
                if (random) {

                    currentCols = (Integer) spinnerColumns.getValue();
                    currentRows = (Integer) spinnerRows.getValue();
                    if (currentCols < 5 || currentRows < 5) {

                        throw (new IllegalArgumentException());
                    } else {
                        BoardFrame b = new BoardFrame(currentRows, currentCols);
                        b.SetFrame(currentRows, currentCols);
                        b.AddRandomShips(currentRows, currentCols);
                        b.ScoreMethod(adjustedScoreMethod);
                        introWAV.stop();
                        introWAV.flush();
                        introWAV.close();
                        dispose();

public static void SetIntroWAV(Clip clip){

    introWAV=clip;
}

public static void play(File file) {
    try {
        Clip sound = AudioSystem.getClip();
        sound.open(AudioSystem.getAudioInputStream(file));
        SetIntroWAV(sound);
        sound.start();

    } catch (Exception e) {
        System.out.println(e);
    }
}

我尝试了其他方法,比如在play类中使用while循环,“if else”语句,。。。有人知道怎么解决这个问题吗?提前谢谢!

jtjikinw

jtjikinw1#

最好的做法是 Clip 变量是加载和打开,然后保存在内存中。这可以在管理声音效果的类中完成。在那个类中,有一个clip作为示例变量,预加载并在构造函数中打开它。
这个类也可以有两个从游戏中调用的方法。

public void play() {
    clip.setFramePosition(0); // ensures Clip will start from the beginning
    clip.start();
}

public void stop() {
    clip.stop();
}

有了这种结构,管理多个声音也变得更容易了。例如,您可以拥有此声音管理类的两个示例,并将每个示例设置为不同的声音源。然后,你可以随时停止一个,开始另一个。

yqhsw0fo

yqhsw0fo2#

罪魁祸首是你生命的一部分 play 方法。每当你想播放任何声音,你也会打电话 SetIntroWAV 内部。这会导致你 introWAV 正在设置变量。
这就是为什么这是一个问题:你第一次打电话 play ,播放您的介绍音并 introWAV 具有正确的值。但是,一旦你开始你的游戏和发挥不同的声音(即使用 buttonPressedPath )你的 introWAV 变量设置为不同的值:最近启动的声音。当你试图阻止你的声音播放时,你正在使用 introWAV 实际上已经不包含你的介绍音了。相反,这将导致您最近播放的声音被停止,因为这是什么 introWAV 现在正在举行。
要解决这个问题,只需设置 introWAV 变量一次,而不是每次 play 被称为。有多种方法可以做到这一点,包括:
你可以让你的 play 方法返回结果 Clip 之后将播放:

public static Clip play(File file) {
    Clip sound = null;
    try {
        sound = AudioSystem.getClip();
        sound.open(AudioSystem.getAudioInputStream(file));
        sound.start();
    } catch (Exception e) {
        System.out.println(e);
    } finally {
        return sound;
    }
}

然后可以使用此返回值调用 SetIntroWAV 一次: SetIntroWAV(play(introPath)); 您还可以将此返回值用于其他目的,例如保留对声音的本地引用。但是,您不必每次都使用它,也可以在不需要该引用时忽略它。
你可以重写你的 play 方法还包含一个参数,告诉该方法您尝试播放的声音是否是简介声音:

public static void play(File file, boolean intro) {
    try {
        Clip sound = AudioSystem.getClip();
        sound.open(AudioSystem.getAudioInputStream(file));
        if(intro) {
            SetIntroWAV(sound);
        }
        sound.start();
    } catch (Exception e) {
        System.out.println(e);
    }
}

这也会导致 SetIntroWAV 只打过一次电话。
我还建议您为此使用更多的面向对象编程风格,因为它可以使这些事情更明显,更容易解决。例如,可以为音频播放和游戏创建单独的类。

相关问题