Capturing speaker output in Java

2019-08-05 08:43发布

问题:

Using Java is it possible to capture the speaker output? This output is not being generated by my program but rather by other running applications. Can this be done with Java or will I need to resort to C/C++?

回答1:

I had a Java based app. that used Java Sound to tap into the sound flowing through the system to make a trace of it. It worked well on my own (Windows based) machine, but failed completely on some others.

It was determined that in order to get it working on those machines, would take nothing short of an audio loop-back in either software or hardware (e.g. connect a lead from the speaker 'out' jack to the microphone 'in' jack).

Since all I really wanted to do was plot the trace for music, and I figured how to play the target format (MP3) in Java, it became unnecessary to pursue the other option further.

(And I also heard that Java Sound on Mac. was horribly broken, but I never looked closely into it.)



回答2:

Java is not the best tool when dealing with the OS. If you need/want to use it for this task, probably you will end using Java Native Interface (JNI), linking to libraries compiled in other languages (probably c/c++).



回答3:

Take an AUX cable, connect to HEADPHONE JACK and other end to MICROPHONE JACK and run this code

https://www.codejava.net/coding/capture-and-record-sound-into-wav-file-with-java-sound-api

 import javax.sound.sampled.*;
    import java.io.*;

public class JavaSoundRecorder {
    // record duration, in milliseconds
    static final long RECORD_TIME = 60000;  // 1 minute

// path of the wav file
File wavFile = new File("E:/Test/RecordAudio.wav");

// format of audio file
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;

// the line from which audio data is captured
TargetDataLine line;

/**
 * Defines an audio format
 */
AudioFormat getAudioFormat() {
    float sampleRate = 16000;
    int sampleSizeInBits = 8;
    int channels = 2;
    boolean signed = true;
    boolean bigEndian = true;
    AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
                                         channels, signed, bigEndian);
    return format;
}

/**
 * Captures the sound and record into a WAV file
 */
void start() {
    try {
        AudioFormat format = getAudioFormat();
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

        // checks if system supports the data line
        if (!AudioSystem.isLineSupported(info)) {
            System.out.println("Line not supported");
            System.exit(0);
        }
        line = (TargetDataLine) AudioSystem.getLine(info);
        line.open(format);
        line.start();   // start capturing

        System.out.println("Start capturing...");

        AudioInputStream ais = new AudioInputStream(line);

        System.out.println("Start recording...");

        // start recording
        AudioSystem.write(ais, fileType, wavFile);

    } catch (LineUnavailableException ex) {
        ex.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

/**
 * Closes the target data line to finish capturing and recording
 */
void finish() {
    line.stop();
    line.close();
    System.out.println("Finished");
}

/**
 * Entry to run the program
 */
public static void main(String[] args) {
    final JavaSoundRecorder recorder = new JavaSoundRecorder();

    // creates a new thread that waits for a specified
    // of time before stopping
    Thread stopper = new Thread(new Runnable() {
        public void run() {
            try {
                Thread.sleep(RECORD_TIME);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            recorder.finish();
        }
    });

    stopper.start();

    // start recording
    recorder.start();
}

}