我想构建一个同时记录来自两个USB麦克风声音的应用程序,并将每个录音存储在不同的文件中。到目前为止,我已经设法构建应用程序,只适合一个麦克风,它工作正常。其结构如下:
阅读配置文件
找到所有支持录制的混音器
根据配置文件
将所需混音器的音频录制到字节数组
将字节数组写入文件
应用程序中出现的前3个步骤是否需要一个或两个麦克风,但我想同时开始录制两个麦克风,并开始在一个单独的线程上写入每个字节数组,因为它有点时间消费和干扰音频录制过程,这是一个循环内部。这是我到目前为止所尝试的:
recorder.readConfig(configFile);
recorder.showAvailableMixers();
recorder.selectMixer();
while (true) {
final byte[] audioBytes = recorder.recordAudio(recorder.firstMixer);
new Thread() {
@Override
public void run() {
try {
Thread.sleep(1000);
final byte[] audioBytes2 = recorder.recordAudio(recorder.secondMixer);
recorder.writeToDisk(audioBytes2);
} catch (InterruptedException | LineUnavailableException | IOException ex) {
Logger.getLogger(ContinuousAudioRecording.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
recorder.writeToDisk(audioBytes);
}
这是一个有点简化的版本,因为它不使用另一个线程写入磁盘。我介绍了1s睡眠,因为我写的文件的名称严格依赖于当前时间,所以我想避免覆盖。我在这里写的程序介绍了两个录音之间的主要延迟,我期待它们录制几乎相同的声音(差异为1秒)。
你能告诉我我做错了什么或者我该如何解决这个问题?我是新手使用线程,我花了一整天时间寻找教程和示例,但我还没有找到一个解决我的程序的复杂性。谢谢!
编辑25.08:我已经设法通过创建另一个记录器对象来解决问题,并在另一个线程上再次执行相同的操作。它不漂亮,绝对不是最佳的,但它是一种解决方法。我还改变了写入磁盘的方法,现在它也依赖于用于录制的麦克风。如果您希望改进它或使用类似的东西,您可以在下面找到我的新代码。希望它能帮助将来的某个人。
final ContinuousAudioRecording recorder = new ContinuousAudioRecording();
recorder.setConfigPath(ContinuousAudioRecording.class.getResource("config.prop").toString().replace("file:", ""));
recorder.readConfig(new File(recorder.getConfigPath()));
recorder.showAvailableMixers();
recorder.selectMixer();
final ContinuousAudioRecording recorder2 = new ContinuousAudioRecording();
recorder2.setConfigPath(ContinuousAudioRecording.class.getResource("config.prop").toString().replace("file:", ""));
recorder2.readConfig(new File(recorder.getConfigPath()));
recorder2.showAvailableMixers();
recorder2.selectMixer();
while (true) {
new Thread(){
@Override
public void run(){
try {
final byte[] _audioBytes = recorder.recordAudio(recorder.firstMixer);
new Thread(){
@Override
public void run(){
try {
recorder.writeToDisk(_audioBytes,recorder.firstMixer.getMixerInfo().getName().replace(" ", ""));
} catch (IOException ex) {
Logger.getLogger(ContinuousAudioRecording.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
} catch (LineUnavailableException | IOException ex) {
Logger.getLogger(ContinuousAudioRecording.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
final byte[] _audioBytes2 = recorder2.recordAudio(recorder.secondMixer);
new Thread(){
@Override
public void run(){
try {
recorder2.writeToDisk(_audioBytes2,recorder2.secondMixer.getMixerInfo().getName().replace(" ", ""));
} catch (IOException ex) {
Logger.getLogger(ContinuousAudioRecording.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
} catch (LineUnavailableException | IOException ex) {
Logger.getLogger(ContinuousAudioRecording.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
Thread.sleep((recorder.recordingLength+1)*1000);
}
}
我已添加最后一次睡眠,以便新录制将在上一次录制结束后开始。我还在录音之间又给了它一秒钟,因为它需要一段时间才能执行所有这些指令(不是一整秒,而只是为了确保)。否则,它会尝试打开之前未关闭的TargetDataLine
,并导致异常。