Java:如何使用麦克风输入作为JavaFX媒体播放器的输入?

标签 java javafx media javasound

我想使用 JavaFX 媒体播放器实时播放麦克风输入(以分析其频率)。问题是,MediaPlayer 只接受字符串作为源。我知道如何将麦克风输入写入字节数组和文件中。

使用字节数组作为 MediaPlayer 的源(对我来说)是不可能的。我尝试使用临时文件,但这会导致以下错误:

Exception in thread "JavaFX Application Thread" MediaException: MEDIA_UNSUPPORTED : Empty signature!

我认为这是因为我正在使用文件作为输入,同时我仍在向其中写入新数据。到目前为止我的完整代码:

public class Music {

static AudioFormat format;
static DataLine.Info info;

public static void input(int i, int j, int pinState) {
    format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);

    try {
        info = new DataLine.Info(TargetDataLine.class, format);
        final TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(info);
        targetLine.open();

        AudioInputStream audioStream = new AudioInputStream(targetLine);

        File temp = File.createTempFile("Input", ".wav");
        temp.deleteOnExit();

        Thread targetThread = new Thread() {
            public void run() {
                targetLine.start();
                try {
                    AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, temp);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

        targetThread.start();

        Media media = new Media(temp.toURI().toURL().toString());
        MediaPlayer player = new MediaPlayer(media);
        player.setAudioSpectrumThreshold(-100);
        player.setMute(false);
        player.setAudioSpectrumListener(new AudioSpectrumListener() {
             @Override  
             public void spectrumDataUpdate(double timestamp, double duration, float[] magnitudes, float[] phases) {
                 if(Var.nodeController[i] == 3) { //testing if the targetLine should keep on capturing sound
                 } else {
                     targetLine.stop();
                     targetLine.close();
                     player.stop();
                 }
             }
        });
        player.play();
    } catch (LineUnavailableException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}    

}

我需要找到一个解决方案来使用麦克风输入作为 MediaPlayer 输入,可以使用文件或字节数组或任何其他可能的解决方案。

最佳答案

我推测以下库可能会有所帮助。 https://github.com/SzymonKatra/AudioAnalyzer

请注意,它使用 FFmpeg声称是:

A complete, cross-platform solution to record, convert and stream audio and video.

关键组件(根据我的粗略浏览)似乎是类 FFTAnalyzer.java文档称其基于 Princeton 中的 FFT 代码/算法。

因此,基本计划(我认为)如下:

  1. 从 targetdataline 获取麦克风输入(字节流)
  2. 将 N 帧字节转换为标准化 float 或 double ,并打包为数组发送到 FFTAnalyzer.analyze(double[]样本)
  3. 通过 FFTAnalyzer.getAmplitudes() 请求分析结果
  4. 检查每个均衡带的结果并适当应用平滑
  5. 重复

我不清楚到底需要多少库。由于您不处理视频或跨平台问题,因此可能只需要此库中的一两个类。

关于Java:如何使用麦克风输入作为JavaFX媒体播放器的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54021239/

相关文章:

java - MySQL 或 Hibernate 缓存问题接收旧数据

java - 覆盖 super 变量 Java

没有桌面环境的 CentOS 上的 JavaFX 全屏问题

JavaFX System.setProperty 管理员权限

ffmpeg - 使用 FFmpeg 检索和保存媒体元数据

java - 需要对这种通用类型进行简要描述

java - JSF 项目中的 NetBeans 部署错误

java - 关闭 javafx 窗口处理程序

c# - mediended 事件的触发是否有任何默认时间间隔?

wordpress - WP 媒体文件 url 不附带 https