You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java音频播放器切换音频片段失效及无法播放问题求助

Java音频播放器切换音频片段失效及无法播放问题求助

我最近在做一个Java音频播放器,主要是想加深对栈和GUI的理解。之前选择音频文件后还能正常播放,但现在突然不行了,我对比了之前的代码也没发现哪里改出了问题,终端里也完全没有报错信息。

我翻了Java SE 8的官方文档,也看了不少关于Java音频片段(Clip)的YouTube教程,感觉自己的代码逻辑和学到的内容是一致的,但就是找不到问题根源。另外我还做了个测试:把代码里的current = numberofClips;这行删掉后,两个音频文件里居然只有一个能正常播放,这就让我更困惑了。

下面是我的代码:

播放器主类代码

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.File;
import java.util.Stack;
import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;

public class MusicPlayerGui extends JFrame implements ActionListener {

  // Image centered
  BufferedImage image = null;

  // Colors
  public static final Color BG_Color = Color.BLACK;
  public static final Color FG_Color = Color.WHITE;

  // Song
  JLabel songImage;
  JLabel songTitle;
  JSlider playbackSlider;

  // Toolbar
  JToolBar toolbar;
  JMenuBar menuBar;
  JMenu songMenu;
  JMenuItem loadMusic;
  JMenuItem loadPlaylist;

  // Button
  JPanel playbackBtns;
  JButton prevButton;
  JButton playButton;
  JButton pauseButton;
  JButton nextButton;

  // Music stuff
  Stack<Clip> clips = new Stack<>();
  int next;
  int prev;
  long frames;
  int current = 0;
  float frameRate;
  int numberofClips;
  AudioFormat format;
  boolean play = true;
  boolean first = true;
  double durationInSeconds;
  long seconds;
  boolean playlist;

  public MusicPlayerGui() {
    super("Music Player");
    setSize(400, 600);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setResizable(false);
    setLayout(null);

    getContentPane().setBackground(BG_Color);
    addUiComponents();
  }

  private void addUiComponents() {
    addToolbar();
    addPlaybackBtns();

    songImage = new JLabel(loadImage("./res/record.png"));
    songImage.setBounds(0, 50, getWidth() - 20, 225);
    add(songImage);

    songTitle = new JLabel("Song title");
    songTitle.setBounds(0, 285, getWidth() - 10, 30);
    songTitle.setFont(new Font("Dialog", Font.BOLD, 24));
    songTitle.setForeground(FG_Color);
    songTitle.setHorizontalAlignment(SwingConstants.CENTER);
    add(songTitle);

    playbackSlider = new JSlider();
    playbackSlider.setBounds(getWidth() / 2 - 300 / 2, 365, 300, 40);
    playbackSlider.setBackground(null);
    add(playbackSlider);
  }

  private void addToolbar() {
    toolbar = new JToolBar();
    toolbar.setBounds(0, 0, getWidth(), 30);
    toolbar.setFloatable(false);
    add(toolbar);

    menuBar = new JMenuBar();
    toolbar.add(menuBar);

    songMenu = new JMenu("Song");
    menuBar.add(songMenu);

    loadMusic = new JMenuItem("Load music from directory");
    loadMusic.addActionListener(this);
    songMenu.add(loadMusic);

    loadPlaylist = new JMenuItem("Load playlist from directory");
    loadPlaylist.addActionListener(this);
    songMenu.add(loadPlaylist);
  }

  private void addPlaybackBtns() {
    playbackBtns = new JPanel();
    playbackBtns.setBounds(0, 435, getWidth() - 10, 80);
    playbackBtns.setBackground(null);

    prevButton = new JButton(loadImage("./res/previous.png"));
    prevButton.setBorderPainted(false);
    prevButton.setBackground(null);
    prevButton.addActionListener(this);
    playbackBtns.add(prevButton);

    playButton = new JButton(loadImage("./res/play.png"));
    playButton.setBorderPainted(false);
    playButton.setBackground(null);
    playButton.addActionListener(this);
    playbackBtns.add(playButton);

    pauseButton = new JButton(loadImage("./res/pause.png"));
    pauseButton.setBorderPainted(false);
    pauseButton.setBackground(null);
    pauseButton.setVisible(false);
    pauseButton.addActionListener(this);
    playbackBtns.add(pauseButton);

    nextButton = new JButton(loadImage("./res/next.png"));
    nextButton.setBorderPainted(false);
    nextButton.setBackground(null);
    playbackBtns.add(nextButton);

    add(playbackBtns);
  }

  private ImageIcon loadImage(String imagePath) {
    try {
      BufferedImage image = ImageIO.read(new File(imagePath));
      return new ImageIcon(image);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == loadMusic) {
      JFileChooser fileChooser = new JFileChooser();
      fileChooser.setFileFilter(new FileNameExtensionFilter("Music Files", "wav"));
      int response = fileChooser.showOpenDialog(null);
      if (response == JFileChooser.APPROVE_OPTION) {
        File file = new File(fileChooser.getSelectedFile().getAbsolutePath());

        try (AudioInputStream aS = AudioSystem.getAudioInputStream(file)) {
          if (play == true) {
            enablePlayButton();
            clips.get(current).stop();
          }

          numberofClips++;
          Clip clip = AudioSystem.getClip();
          current = numberofClips;


          format = aS.getFormat();
          frames = aS.getFrameLength();
          durationInSeconds = frames / format.getFrameRate();
          seconds = (long) (durationInSeconds % 60);

          clip.open(aS);
          clips.push(clip);

        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
          System.out.println(ex);
        }
      }
    }

    if (e.getSource() == loadPlaylist) {
      JFileChooser fileChooser = new JFileChooser();
      fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

      int response = fileChooser.showOpenDialog(null);
      if (response == JFileChooser.APPROVE_OPTION) {
        File files = new File(fileChooser.getSelectedFile().getAbsolutePath());

        for (File file : files.listFiles()) {

          try (AudioInputStream aS = AudioSystem.getAudioInputStream(file)) {
            if (play == true) {
              enablePlayButton();
              clips.get(current).stop();
            }

            numberofClips++;
            Clip clip = AudioSystem.getClip();

            format = aS.getFormat();
            frames = aS.getFrameLength();
            durationInSeconds = frames / format.getFrameRate();
            seconds = (long) (durationInSeconds % 60);

            playlist = true;
            clip.open(aS);
            clips.push(clip);

          } catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
            System.out.println(ex);
          }
        }
      }
    }

    if (e.getSource() == playButton) {
      enablePauseButton();
      clips.get(current).start();

      next = current + 1;
      prev = current - 1;

      if (playlist) {
        if ((clips.empty() && clips.get(current).isRunning() != false) && next > numberofClips) {
          enablePauseButton();
          clips.get(next).start();
          current = next;
        }
      }
    }

    if (e.getSource() == pauseButton) {
      enablePlayButton();
      clips.get(current).stop();
    }

    if (e.getSource() == prevButton) {
      if (first != true && prev < 0) {
        enablePlayButton();
        clips.get(current).stop();
        clips.get(prev).start();
        current = prev;
        next = current + 1;
        prev = current - 1;
      }
    }
  }

  void enablePauseButton() {
    JButton playBtn = (JButton) playbackBtns.getComponent(1);
    JButton pauseBtn = (JButton) playbackBtns.getComponent(2);

    playBtn.setVisible(false);
    playBtn.setEnabled(false);

    pauseBtn.setVisible(true);
    pauseBtn.setEnabled(true);
    play = true;
  }

  void enablePlayButton() {
    JButton playBtn = (JButton) playbackBtns.getComponent(1);
    JButton pauseBtn = (JButton) playbackBtns.getComponent(2);

    playBtn.setVisible(true);
    playBtn.setEnabled(true);

    pauseBtn.setVisible(false);
    pauseBtn.setEnabled(false);
    play = false;
  }
}

主运行类代码

import javax.swing.SwingUtilities;

public class Main {

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

      @Override
      public void run() {
        new MusicPlayerGui().setVisible(true);;
      }
    });
  }
}

备注:内容来源于stack exchange,提问作者Fer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:59:28