java - 如何在 javax.sound.sampled.Line 上播放/录制声音

标签 java audio javax.sound.sampled

我有一个数组,其中填充了所有当前连接的麦克风的 javax.sound.sampled.Line.Info 对象

Info[] sourceInfos = AudioSystem.getSourceLineInfo(Port.Info.MICROPHONE);

使用它们我可以获得所有麦克风的线路

for (Info sourceInfo : sourceInfos) {
    Line sourceLine = AudioSystem.getLine(sourceInfo);
    // record sound from those lines
}

演讲者也是如此

Info[] sourceInfos = AudioSystem.getSourceLineInfo(Port.Info.SPEAKER);
for (Info sourceInfo : sourceInfos) {
    Line sourceLine = AudioSystem.getLine(sourceInfo);
    // play sound on those lines
}

现在我只需要弄清楚如何在 Line 上播放声音以及如何从 Line 录制声音。这是我卡住的地方,找不到解决方案。

所以只是说一下,问题是,我如何读取/写入一行?
谢谢
巴施迪

最佳答案

您可以尝试此示例来捕获和播放音频。它基于 Java Sound API 文档中提供的示例。

以下是您可以引用的资源:

  1. Accessing Audio System Resources
  2. Capturing audio .
  3. Playing audio .

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.Mixer;
    import javax.sound.sampled.SourceDataLine;
    import javax.sound.sampled.TargetDataLine;
    
    public class Audio {
    
    boolean stopCapture = false;
    ByteArrayOutputStream byteArrayOutputStream;
    AudioFormat audioFormat;
    TargetDataLine targetDataLine;
    AudioInputStream audioInputStream;
    SourceDataLine sourceDataLine;
    byte tempBuffer[] = new byte[500];
    
    public static void main(String[] args) {
        Audio audio = new Audio();
        audio.captureAudio();
    
    }
    
    private AudioFormat getAudioFormat() {
        float sampleRate = 8000.0F;
        int sampleSizeInBits = 16;
        int channels = 1;
        boolean signed = true;
        boolean bigEndian = true;
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    }
    
    private void captureAudio() {
        try {
    
            /* ~~~~~ UPDATE THIS PART OF CODE ~~~~~*/
    
            Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();    //get available mixers
            System.out.println("Available mixers:");
            for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
                System.out.println(mixerInfo[cnt].getName());
            }
            audioFormat = getAudioFormat();     //get the audio format
    
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
    
            Mixer mixer = AudioSystem.getMixer(mixerInfo[3]);   //getting the mixer for capture device
    
            /* ~~~~~ UPDATE THIS PART OF CODE ~~~~~*/ 
    
            targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
            targetDataLine.open(audioFormat);
            targetDataLine.start();
    
            DataLine.Info dataLineInfo1 = new DataLine.Info(SourceDataLine.class, audioFormat);
            sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo1);
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();
    
            Thread captureAndPlayThread = new captureAndPlayThread();   //thread to capture and play audio
            captureAndPlayThread.start();
    
        } catch (LineUnavailableException e) {
            System.out.println(e);
            System.exit(0);
        }
    }
    
    class captureAndPlayThread extends Thread {
    
        @Override
        public void run() {
            byteArrayOutputStream = new ByteArrayOutputStream();
            stopCapture = false;
            try {
                int readCount;
                while (!stopCapture) {
                    readCount = targetDataLine.read(tempBuffer, 0, tempBuffer.length);  //capture sound into tempBuffer
                    if (readCount > 0) {
                        byteArrayOutputStream.write(tempBuffer, 0, readCount);
                        sourceDataLine.write(tempBuffer, 0, 500);   //playing audio available in tempBuffer
                    }
                }
                byteArrayOutputStream.close();
            } catch (IOException e) {
                System.out.println(e);
                System.exit(0);
            }
        }
    }
    
    }
    

    `

编辑:请使用此代码更新之前的代码。以下代码片段仅在支持麦克风时选择混音器,即 TargetDataLine。同样,您可以为扬声器做,即 SourceDataLine。

        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();    //get available mixers
        System.out.println("Available mixers:");
        Mixer mixer = null;
        for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
            System.out.println(cnt + " " + mixerInfo[cnt].getName());
            mixer = AudioSystem.getMixer(mixerInfo[cnt]);

            Line.Info[] lineInfos = mixer.getTargetLineInfo();
            if (lineInfos.length >= 1 && lineInfos[0].getLineClass().equals(TargetDataLine.class)) {
                System.out.println(cnt + " Mic is supported!");
                break;
            }
        }

        audioFormat = getAudioFormat();     //get the audio format
        DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);

关于java - 如何在 javax.sound.sampled.Line 上播放/录制声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32347274/

相关文章:

java - 连接两个 WAV 文件失败

java - 粗体样式在 pdf 输出中不起作用

ios - AVAudioPlayer在播放时崩溃

Javax.sound 在 Android 中不可用

audio - 播放文件时如何用pyglet停止音频?

qt - QMediaPlayer 不播放某些 mp3 文件

Java Mockito 和委托(delegate)

java - 静态变量的奇怪行为

java - 没有xml配置的spring是不扫描包的