录音在java中不工作 [英] Sound recording not working in java

查看:160
本文介绍了录音在java中不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过正在我的Windows机器上通过扬声器/耳机发挥Java来录制声音。

I am trying to record sound through java that is being played on my windows machine through speakers/headphone.

我坚持是我没有找到一个单一的TargetDataLine的是,AudioSystem支持的问题。

The problem I am stuck with is I am not finding a single TargetDataLine that the AudioSystem supports.

我试过getSupportedFormats()方法来检查是否有任何TargetDataLine的我能得到但我得到了0线。如果改变getSupportedFormats的参数的SourceDataLine我拿到9可用的线路。

I tried getSupportedFormats() method to check whether there is any TargetDataLine that I can get however I got 0 lines. If a change the argument in getSupportedFormats to SourceDataLine I got 9 available lines.

     Vector<AudioFormat> formats = getSupportedFormats(TargetDataLine.class);
    System.out.println(formats.size());

     public static Vector<AudioFormat> getSupportedFormats(Class<?> dataLineClass) {
    /*
     * These define our criteria when searching for formats supported
     * by Mixers on the system.
     */
    float sampleRates[] = { (float) 8000.0, (float) 16000.0, (float) 44100.0 };
    int channels[] = { 1, 2 };
    int bytesPerSample[] = { 2 };

    AudioFormat format;
    DataLine.Info lineInfo;

    //SystemAudioProfile profile = new SystemAudioProfile(); // Used for allocating MixerDetails below.
    Vector<AudioFormat> formats = new Vector<AudioFormat>();

    for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
        for (int a = 0; a < sampleRates.length; a++) {
            for (int b = 0; b < channels.length; b++) {
                for (int c = 0; c < bytesPerSample.length; c++) {
                    format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                            sampleRates[a], 8 * bytesPerSample[c], channels[b], bytesPerSample[c],
                            sampleRates[a], false);
                    lineInfo = new DataLine.Info(dataLineClass, format);
                    if (AudioSystem.isLineSupported(lineInfo)) {
                        /*
                         * TODO: To perform an exhaustive search on supported lines, we should open
                         * TODO: each Mixer and get the supported lines. Do this if this approach
                         * TODO: doesn't give decent results. For the moment, we just work with whatever
                         * TODO: the unopened mixers tell us.
                         */
                        if (AudioSystem.getMixer(mixerInfo).isLineSupported(lineInfo)) {
                            formats.add(format);
                        }
                    }
                }
            }
        }
    }
    return formats;
}

另外,我已经试过大部分由audioFormats方法仍然没能找到一个行返回的格式。

Also I have tried most of the formats returned by the audioFormats method still not able to find a line.

public List<AudioFormat> audioFormats() throws LineUnavailableException{
Mixer.Info[] mi = AudioSystem.getMixerInfo();
List<AudioFormat> audioFormats = new ArrayList<AudioFormat>();
for (Mixer.Info info : mi) {
    System.out.println("info: " + info);
    Mixer m = AudioSystem.getMixer(info);
    System.out.println("mixer " + m);
    Line.Info[] sl = m.getSourceLineInfo();
    for (Line.Info info2 : sl) {
        System.out.println("    info: " + info2);
        Line line = AudioSystem.getLine(info2);
        if (line instanceof SourceDataLine) {
            SourceDataLine source = (SourceDataLine) line;

            DataLine.Info i = (DataLine.Info) source.getLineInfo();
            for (AudioFormat format : i.getFormats()) {
                audioFormats.add(format);
                System.out.println("    format: " + format);
            }
        }
    }
}
return audioFormats;
}

下面是我曾尝试将样品类

Here is the sample class that I have tried

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


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

// path of the wav file
File wavFile = new File("spacemusic.wav");

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

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

/**
 * Defines an audio format
 */
AudioFormat getAudioFormat() {
    float sampleRate = 44100;
    int sampleSizeInBits = 16;
    int channels = 2; 
    boolean bigEndian = false;
    Encoding encoding = Encoding.PCM_SIGNED;
    int frameSize = 4;
    float framRate = 44100;
   /* AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
                                     channels, signed, bigEndian);*/
    AudioFormat format = new AudioFormat(encoding, sampleRate, sampleSizeInBits, channels, frameSize, framRate, bigEndian);
    return format;
}

/**
 * Captures the sound and record into a WAV file
 * @throws UnsupportedAudioFileException 
 */
void start() throws UnsupportedAudioFileException {
    try {

        AudioFormat format = getAudioFormat();  
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);  
        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
 * @throws UnsupportedAudioFileException 
 */
public static void main(String[] args) throws UnsupportedAudioFileException {
    final Recorder recorder = new Recorder();

    // 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();
}

}

这是如何获取支持,这样我可以带录制前进行的任何想法。谢谢

Any idea on how to get a line that is supported so that I can go ahead with recording. Thanks

推荐答案

您可以试试这个类。对我来说,完美的作品。我捕获并保存从麦克风音频到一个文件中(即file.au)

You can try this class. For me that works perfectly. I capture and save audio from mic into a file (ie. file.au)

首先,复制这一切,并在项目中创建一个新类

First, copy all of it and create a new class in your project

`

  import javax.swing.*;
  import java.awt.*;
  import java.awt.event.*;
  import java.io.*;

  import javax.sound.sampled.*;

 // Class for capturing and saving into file, audio from mic




public class AudioCaptureAndSaveIntoFile {

boolean stopCapture = false;
ByteArrayOutputStream byteArrayOutputStream;
AudioFormat audioFormat;
TargetDataLine targetDataLine;
AudioInputStream audioInputStream;
SourceDataLine sourceDataLine;

FileOutputStream fout;
AudioFileFormat.Type fileType;

public AudioRecorder() {
}

// Captures audio input
// from mic.
// Saves input in
// a ByteArrayOutputStream.
public void captureAudio() {
    try {

        audioFormat = getAudioFormat();
        DataLine.Info dataLineInfo = new DataLine.Info(
                TargetDataLine.class, audioFormat);
        targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
        targetDataLine.open(audioFormat);
        targetDataLine.start();

        // Thread to capture from mic
        // This thread will run till stopCapture variable
        // becomes true. This will happen when saveAudio()
        // method is called.
        Thread captureThread = new Thread(new CaptureThread());
        captureThread.start();
    } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
    }
}

// Saves the data from
// ByteArrayOutputStream
// into a file
public void saveAudio(File filename) {
    stopCapture = true;
    try {

        byte audioData[] = byteArrayOutputStream.toByteArray();

        InputStream byteArrayInputStream = new ByteArrayInputStream(
                audioData);
        AudioFormat audioFormat = getAudioFormat();
        audioInputStream = new AudioInputStream(byteArrayInputStream,
                audioFormat, audioData.length / audioFormat.getFrameSize());
        DataLine.Info dataLineInfo = new DataLine.Info(
                SourceDataLine.class, audioFormat);
        sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
        sourceDataLine.open(audioFormat);
        sourceDataLine.start();

        // This thread will actually do the job
        Thread saveThread = new Thread(new SaveThread(filename));
        saveThread.start();
    } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
    }
}

public AudioFormat getAudioFormat() {
    float sampleRate = 8000.0F;
    // You can try also 8000,11025,16000,22050,44100
    int sampleSizeInBits = 16;
    int channels = 1;
    boolean signed = true;
    boolean bigEndian = false;
    return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
            bigEndian);
}

class CaptureThread extends Thread {
    // temporary buffer
    byte tempBuffer[] = new byte[10000];

    public void run() {
        byteArrayOutputStream = new ByteArrayOutputStream();
        stopCapture = false;
        try {
            while (!stopCapture) {

                int cnt = targetDataLine.read(tempBuffer, 0,
                        tempBuffer.length);
                if (cnt > 0) {

                    byteArrayOutputStream.write(tempBuffer, 0, cnt);

                }
            }
            byteArrayOutputStream.close();
        } catch (Exception e) {
            System.out.println(e);
            System.exit(0);
        }
    }
}

class SaveThread extends Thread {
    // Set a file from saving from ByteArrayOutputStream
    File fname;

    public SaveThread(File fname) {
        this.fname = fname;
    }

    //
    byte tempBuffer[] = new byte[10000];

    public void run() {
        try {
            int cnt;

            if (AudioSystem.isFileTypeSupported(AudioFileFormat.Type.AU,
                    audioInputStream)) {
                AudioSystem.write(audioInputStream,
                        AudioFileFormat.Type.AU, fname);
            }

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

  }

  ` 

在项目中使用上面的类,如下所示:

In your project use the above class, like this:

要捕获麦克风音频到一个临时ByteArrayOutput对象,第一:

To capture audio from mic into a temporary ByteArrayOutput object, first :

audiorec =新AudioCaptureAndSaveIntoFile();
   audiorec.captureAudio();

和保存到一个文件:

 audiorec.saveAudio(savefile); 

注意:您保存的文件应即结束。 .AU或.WAV

Note: You save file should end with ie. ".au" or ".wav"

这篇关于录音在java中不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆