java - 如何使用 AudioInputStream 的中间录制 x 秒的文件,并继续流式传输?

标签 java sphinx4

我有一个 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/

相关文章:

java - 将 ServletContext 属性的内容保存在 int 变量中

java - 我可以提交引用 POJO(即不仅仅是字符串或 boolean 值)字段的 Struts 表单吗?

java - 我们如何更改标签中的行?

cmusphinx - CMU Sphinx 德语发音词典

java - 使用 Sphinx4 java api 识别实时语音

java - 在没有 Maven 的情况下使用 sphinx4 jar 时出错

java - 在Java中优化Collat​​z猜想

java - 验证 "Copy All"按钮中从组合框到列表的数据

Java 狮身人面像 "Answers Itself"

java - Sphinx4 荷兰语语言模型不起作用