Java:如何使用麦克风输入作为JavaFX媒体播放器的输入? [英] Java: How to use microphone input as input for the JavaFX media player?

查看:223
本文介绍了Java:如何使用麦克风输入作为JavaFX媒体播放器的输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to play the microphone input in realtime using the JavaFX media player (to analyse its frequencies). The problem is, that the MediaPlayer only accepts Strings as source. I know how to write the microphone input into a byte array and into a file.

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

Using the byte array as source for the MediaPlayer is (for me) not possible. I tried using a temporary file, but that causes the following error:

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

我认为这是因为我在使用文件作为输入而我还在写新内容数据进入它。我的完整代码到现在为止:

I think this is, because I'm using a file as input while I'm still writing new data into it. My full code until now:

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输入,使用文件或字节数组或任何其他可能的解决方案。

I need to find a solution to use the microphone input as MediaPlayer input, either using a file or a byte array or any other possible solution.

推荐答案

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

I am going to speculate that the following library might be helpful. https://github.com/SzymonKatra/AudioAnalyzer

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

Note that it makes use of FFmpeg which claims to be:


一个完整的跨平台解决方案,用于记录,转换和流式传输
音频和视频。

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

关键组件(基于我粗略的查看)似乎是类 FFTAnalyzer.java 基于来自普林斯顿

The key component (based on my cursory look-over) seems to be the class FFTAnalyzer.java which the documentation says is based upon an FFT code/algorithm from Princeton.

所以,基本计划(我相信)将如下:

So, the basic plan (I believe) would be the following:


  1. 从targetdataline获取麦克风输入(字节流)

  2. 将N帧字节转换为规范化的浮点数或双精度数据包并作为数组打包发送到FFTAnalyzer.analyze(double [] samples)

  3. 通过FFTAnalyzer.getAmplitudes()
  4. 请求分析结果
  5. 检查每个均衡带的结果并根据需要应用平滑

  6. 重复

  1. obtain microphone input (a stream of bytes) from targetdataline
  2. convert N frames of bytes to normalized floats or doubles and package as an array to send to FFTAnalyzer.analyze(double[] samples)
  3. request the analysis results via FFTAnalyzer.getAmplitudes()
  4. examine the result for each equalization band and apply smoothing as appropriate
  5. repeat

我不清楚究竟需要多少库。可能是因为您没有处理视频或跨平台问题,因此只需要此库中的一两个类。

I'm unclear as to exactly how much of the library is needed. It could be that since you are not dealing with video or cross-platform issues, only a class or two from this library would be needed.

这篇关于Java:如何使用麦克风输入作为JavaFX媒体播放器的输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆