📜  如何使用Java播放音频文件

📅  最后修改于: 2021-10-19 06:15:44             🧑  作者: Mango

在这篇文章中,我们将看到,我们如何在纯Java播放音频文件,这里纯的意思是,我们不会使用任何外部库。您可以借助本文创建自己的音乐播放器。 Java内置库仅支持 AIFC、AIFF、AU、SND 和 WAVE 格式。
有 2 个不同的接口可用于此目的 Clip 和 SourceDataLine。在本文中,我们将讨论仅使用 Clip 播放音频文件,并查看 Clip 的各种方法。我们将涵盖以下操作:

  1. 开始。
  2. 暂停。
  3. 恢复。
  4. 重新开始。
  5. 停止
  6. 跳转到播放的特定位置。

使用 Clip 播放音频

Clip 是 javax.sound.sampled 包中的一个Java接口,在 Java7 中引入。
按照以下步骤播放剪辑对象。

  1. 使用 AudioSystem.getAudioInputStream(File file) 创建一个 AudioInputStream 对象。 AudioInputStream 将音频文件转换为流。
  2. 从 AudioSystem 获取剪辑参考对象。
  3. 使用 Clip 接口的 open() 方法流式传输音频输入流,音频数据将从音频输入流中读取到剪辑中。
  4. 将所需的属性设置为剪辑,如帧位置、循环、微秒位置。
  5. 开始剪辑
// Java program to play an Audio
// file using Clip Object
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
  
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
  
public class SimpleAudioPlayer 
{
  
    // to store current position
    Long currentFrame;
    Clip clip;
      
    // current status of clip
    String status;
      
    AudioInputStream audioInputStream;
    static String filePath;
  
    // constructor to initialize streams and clip
    public SimpleAudioPlayer()
        throws UnsupportedAudioFileException,
        IOException, LineUnavailableException 
    {
        // create AudioInputStream object
        audioInputStream = 
                AudioSystem.getAudioInputStream(new File(filePath).getAbsoluteFile());
          
        // create clip reference
        clip = AudioSystem.getClip();
          
        // open audioInputStream to the clip
        clip.open(audioInputStream);
          
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
  
    public static void main(String[] args) 
    {
        try
        {
            filePath = "Your path for the file";
            SimpleAudioPlayer audioPlayer = 
                            new SimpleAudioPlayer();
              
            audioPlayer.play();
            Scanner sc = new Scanner(System.in);
              
            while (true)
            {
                System.out.println("1. pause");
                System.out.println("2. resume");
                System.out.println("3. restart");
                System.out.println("4. stop");
                System.out.println("5. Jump to specific time");
                int c = sc.nextInt();
                audioPlayer.gotoChoice(c);
                if (c == 4)
                break;
            }
            sc.close();
        } 
          
        catch (Exception ex) 
        {
            System.out.println("Error with playing sound.");
            ex.printStackTrace();
          
          }
    }
      
    // Work as the user enters his choice
      
    private void gotoChoice(int c)
            throws IOException, LineUnavailableException, UnsupportedAudioFileException 
    {
        switch (c) 
        {
            case 1:
                pause();
                break;
            case 2:
                resumeAudio();
                break;
            case 3:
                restart();
                break;
            case 4:
                stop();
                break;
            case 5:
                System.out.println("Enter time (" + 0 + 
                ", " + clip.getMicrosecondLength() + ")");
                Scanner sc = new Scanner(System.in);
                long c1 = sc.nextLong();
                jump(c1);
                break;
      
        }
      
    }
      
    // Method to play the audio
    public void play() 
    {
        //start the clip
        clip.start();
          
        status = "play";
    }
      
    // Method to pause the audio
    public void pause() 
    {
        if (status.equals("paused")) 
        {
            System.out.println("audio is already paused");
            return;
        }
        this.currentFrame = 
        this.clip.getMicrosecondPosition();
        clip.stop();
        status = "paused";
    }
      
    // Method to resume the audio
    public void resumeAudio() throws UnsupportedAudioFileException,
                                IOException, LineUnavailableException 
    {
        if (status.equals("play")) 
        {
            System.out.println("Audio is already "+
            "being played");
            return;
        }
        clip.close();
        resetAudioStream();
        clip.setMicrosecondPosition(currentFrame);
        this.play();
    }
      
    // Method to restart the audio
    public void restart() throws IOException, LineUnavailableException,
                                            UnsupportedAudioFileException 
    {
        clip.stop();
        clip.close();
        resetAudioStream();
        currentFrame = 0L;
        clip.setMicrosecondPosition(0);
        this.play();
    }
      
    // Method to stop the audio
    public void stop() throws UnsupportedAudioFileException,
    IOException, LineUnavailableException 
    {
        currentFrame = 0L;
        clip.stop();
        clip.close();
    }
      
    // Method to jump over a specific part
    public void jump(long c) throws UnsupportedAudioFileException, IOException,
                                                        LineUnavailableException 
    {
        if (c > 0 && c < clip.getMicrosecondLength()) 
        {
            clip.stop();
            clip.close();
            resetAudioStream();
            currentFrame = c;
            clip.setMicrosecondPosition(c);
            this.play();
        }
    }
      
    // Method to reset audio stream
    public void resetAudioStream() throws UnsupportedAudioFileException, IOException,
                                            LineUnavailableException 
    {
        audioInputStream = AudioSystem.getAudioInputStream(
        new File(filePath).getAbsoluteFile());
        clip.open(audioInputStream);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
  
}

在上面的程序中,我们使用了Java的AudioInputStream类来读取音频文件作为流。就像每个Java流一样,如果要再次使用它,则必须对其进行重置。

  • 要暂停播放,我们必须停止播放器并将当前帧存储在一个对象中。这样在恢复时我们就可以使用它。恢复时,我们只需要从我们离开的最后一个位置再次播放玩家。
    clip.getMicrosecondPosition() 方法返回音频的当前位置,并且 clip.setMicrosecondPosition(long position) 设置音频的当前位置。
  • 要停止播放,您必须关闭剪辑,否则它将保持打开状态。我还使用了 clip.loop(Clip.LOOP_CONTINOUSLY) 进行测试。因为 wav 文件通常很小,所以我循环播放了我的。

    要点:

    1. 在退出程序之前,请始终关闭打开的流和资源。
    2. 您必须先停止剪辑,然后才能再次播放。所以要保持适当的检查。
    3. 如果要再次使用 AudioInputStream,则必须将其重置。