我有一个 Java 桌面程序 (Sphinx4),它持续通过麦克风监听关键字。然后,我希望它将音频跟随关键字录制到文件(WAVE、bigEndian)中,并将其发送到外部 Web API 进行处理。好消息是,我的关键字可以正常工作,并且我创建了一种在我需要时开始录制到文件的方法,但是当它位于音频输入流中间时,我无法在不切断的情况下停止输出整个流。
我可以使用以下方法成功输出文件:
AudioSystem.write(inputStream, AudioFileFormat.Type.WAVE, new File("test3.wav"));
然而,这是线程阻塞并且将永远持续下去(因为这是连续监听)。经过几个小时的研究后,我希望有人能提供一个简单的解决方案,希望我错过了。
起初,我认为我需要做的就是将其视为正常的输入流,但如果不设置元信息,文件将无法播放:
byte[] buffer = new byte[1024];
FileOutputStream out = new FileOutputStream("test.wav");
while ((read = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
基本上,我的计划是在 while 循环中添加一个 boolean 变量来检测何时停止然后关闭它,虽然它确实创建了一个文件,但它无法播放。
音频流通过以下方式启动:
AudioFormat format =
new AudioFormat(sampleRate, sampleSize, 1, signed, bigEndian);
try {
line = AudioSystem.getTargetDataLine(format);
line.open();
} catch (LineUnavailableException e) {
throw new IllegalStateException(e);
}
inputStream = new AudioInputStream(line);
那么我该怎么做才能在流中间获取音频文件并录制“x”秒呢?
最佳答案
尝试了各种方法,终于找到了解决办法。我的目标是从 AudioInputStream 录制音频文件,但对其调用“close()”基本上破坏了整个应用程序,因为其他各种类也需要输入流。在我的用例中,关闭和启动新流并不实际。
我决定研究克隆输入流,它正是我所需要的。总之,真正需要的是从 AudioInputStream 创建 ByteArrayOutputStream,然后根据需要写出字节。完成后,关闭 ByteArrayOutputStream 并执行所需的任何处理。通过这样做,原始输入流不必以任何方式被触及或中断。希望这可以帮助其他遇到同样问题的人:
int numBytesRead;
byte[] data = new byte[line.getBufferSize()];
while (isrecording) {
numBytesRead = line.read(data, 0, data.length);
baos.write(data, 0, numBytesRead);
}
try {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray());
AudioInputStream stream = new AudioInputStream(byteArrayInputStream, format, baos.toByteArray().length);
AudioSystem.write(stream, AudioFileFormat.Type.WAVE, new File("test.wav"));
baos.close();
byteArrayInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
关于java - 如何使用 AudioInputStream 的中间录制 x 秒的文件,并继续流式传输?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57320150/