如何使用Xuggler获取用于编码的音频

我正在编写一个记录屏幕和音频的应用程序。 虽然屏幕录制效果很好,但我很难使用JDK库获取原始音频。 这是代码:

try { // Now, we're going to loop long startTime = System.nanoTime(); System.out.println("Encoding Image....."); while (!Thread.currentThread().isInterrupted()) { // take the screen shot BufferedImage screen = robot.createScreenCapture(screenBounds); // convert to the right image type BufferedImage bgrScreen = convertToType(screen, BufferedImage.TYPE_3BYTE_BGR); // encode the image writer.encodeVideo(0, bgrScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS); /* Need to get audio here and then encode using xuggler. Something like WaveData wd = new WaveData(); TargetDataLine line; AudioInputStream aus = new AudioInputStream(line); short[] samples = getSourceSamples(); writer.encodeAudio(0, samples); */ if (timeCreation < 10) { timeCreation = getGMTTime(); } // sleep for framerate milliseconds try { Thread.sleep((long) (1000 / FRAME_RATE.getDouble())); } catch (Exception ex) { System.err.println("stopping...."); break; } } // Finally we tell the writer to close and write the trailer if // needed } finally { writer.close(); } 

这个页面有一些伪代码

 while(haveMoreAudio()) { short[] samples = getSourceSamples(); writer.encodeAudio(0, samples); } 

但是我应该为getSourceSamples()做些什么呢?

另外,一个额外的问题 – 这种方法可以从多个麦克风中进行选择吗?

另请参见: Xuggler编码和多路复用

尝试这个:

 // Pick a format. Need 16 bits, the rest can be set to anything // It is better to enumerate the formats that the system supports, because getLine() can error out with any particular format AudioFormat audioFormat = new AudioFormat(44100.0F, 16, 2, true, false); // Get default TargetDataLine with that format DataLine.Info dataLineInfo = new DataLine.Info( TargetDataLine.class, audioFormat ); TargetDataLine line = (TargetDataLine) AudioSystem.getLine(dataLineInfo); // Open and start capturing audio line.open(audioFormat, line.getBufferSize()); line.start(); while (true) { // read as raw bytes byte[] audioBytes = new byte[ line.getBufferSize() / 2 ]; // best size? int numBytesRead = 0; numBytesRead = line.read(audioBytes, 0, audioBytes.length); // convert to signed shorts representing samples int numSamplesRead = numBytesRead / 2; short[] audioSamples = new short[ numSamplesRead ]; if (format.isBigEndian()) { for (int i = 0; i < numSamplesRead; i++) { audioSamples[i] = (short)((audioBytes[2*i] << 8) | audioBytes[2*i + 1]); } } else { for (int i = 0; i < numSamplesRead; i++) { audioSamples[i] = (short)((audioBytes[2*i + 1] << 8) | audioBytes[2*i]); } } // use audioSamples in Xuggler etc } 

要选择麦克风,您可能必须这样做:

 Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); // Look through and select a mixer here, different mixers should be different inputs int selectedMixerIndex = 0; Mixer mixer = AudioSystem.getMixer(mixerInfo[ selectedMixerIndex ]); TargetDataLine line = (TargetDataLine) mixer.getLine(dataLineInfo); 

我认为多个麦克风可能会在一个调音台中显示为不同的源数据线。 在这种情况下,您必须打开它们并调用dataLine.getControl(FloatControl.Type.MASTER_GAIN).setValue( volume ); 打开和关闭它们。

请参阅: WaveData.java

来自TargetDataLine的声波

如何在Java中设置SourceDataLine的卷