我正试图通过扬声器/耳机在我的Windows机器上播放的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 :(得分:0)
你可以尝试这个课程。对我来说完美无缺。我将麦克风中的音频捕获并保存到文件中(即。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);
注意:保存文件应以ie结尾。 &#34; .AU&#34;或&#34; .wav&#34;