Java: 如何使用麦克风输入作为 JavaFX 媒体播放器的输入?
Java: How to use microphone input as input for the JavaFX media player?
我想使用 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.
关键组件(基于我粗略的查看)似乎是 class FFTAnalyzer.java which the documentation says is based upon an FFT code/algorithm from Princeton。
所以,基本计划(我相信)如下:
- 从 targetdataline 获取麦克风输入(字节流)
- 将N帧字节转换为规范化的浮点数或双精度数并打包为数组发送到FFTAnalyzer.analyze(double[] samples)
- 通过FFTAnalyzer.getAmplitudes()
请求分析结果
- 检查每个均衡带的结果并适当应用平滑
- 重复
我不清楚到底需要多少库。可能是因为您不处理视频或跨平台问题,所以只需要此库中的一两个 class。
我想使用 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.
关键组件(基于我粗略的查看)似乎是 class FFTAnalyzer.java which the documentation says is based upon an FFT code/algorithm from Princeton。
所以,基本计划(我相信)如下:
- 从 targetdataline 获取麦克风输入(字节流)
- 将N帧字节转换为规范化的浮点数或双精度数并打包为数组发送到FFTAnalyzer.analyze(double[] samples)
- 通过FFTAnalyzer.getAmplitudes() 请求分析结果
- 检查每个均衡带的结果并适当应用平滑
- 重复
我不清楚到底需要多少库。可能是因为您不处理视频或跨平台问题,所以只需要此库中的一两个 class。