2014-02-13 25 views
2

我想通過揚聲器/耳機在Windows機器上播放的java錄製聲音。在java中錄音不工作

我遇到的問題是我找不到AudioSystem支持的單個TargetDataLine。

我試着getSupportedFormats()方法來檢查是否有任何TargetDataLine,但我可以得到0行。如果將getSupportedFormats中的參數更改爲SourceDataLine,我有9行可用。

 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方法返回的大部分格式仍然無法找到一行。

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; 
} 

這裏是我曾嘗試

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

}

如何獲取支持,讓我可以記錄繼續行任何想法樣本類。謝謝

+0

嘿,你能解決這個問題嗎? –

回答

1

你可以試試這個課程。對我來說,完美的作品。我捕獲並保存從麥克風音頻到一個文件中(即file.au)

首先,複製所有的它,在你的項目

`

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

    } 

    ` 

創建一個新的類在項目使用上面的類,如下所示:

爲了捕獲來自麥克風的音頻到臨時ByteArrayOutput對象,第一:

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

,並保存到一個文件:

audiorec.saveAudio(savefile); 

注意:您保存文件應即結束。 「.au」或「.wav」

+0

謝謝你。爲我工作。 :) –