Java: Как использовать микрофонный вход в качестве входа для медиаплеера JavaFX? - PullRequest
0 голосов
/ 03 января 2019

Я хочу воспроизводить микрофонный вход в режиме реального времени, используя медиаплеер 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, используя файл или байтовый массив или любое другое возможное решение.

1 Ответ

0 голосов
/ 03 января 2019

Я собираюсь предположить, что следующая библиотека может быть полезной. https://github.com/SzymonKatra/AudioAnalyzer

Обратите внимание, что он использует FFmpeg , который утверждает, что:

Полное кроссплатформенное решение для записи, преобразования и потоковой передачи аудио и видео.

Ключевым компонентом (основанным на моем беглом просмотре) является класс FFTAnalyzer.java , который, как говорится в документации, основан на коде / алгоритме FFT из Princeton .

Итак, базовый план (я считаю) будет следующим:

  1. получить микрофонный вход (поток байтов) от targettdataline
  2. преобразует N кадров байтов в нормализованные числа с плавающей запятой или удваивает и упаковывает их в массив для отправки в FFTAnalyzer.analyze (double [] samples)
  3. запросить результаты анализа через FFTAnalyzer.getAmplitude ()
  4. проверить результат для каждой полосы выравнивания и применить соответствующее сглаживание
  5. повтор

Мне неясно, сколько именно библиотеки нужно. Возможно, поскольку вы не имеете дело с проблемами с видео или кроссплатформенностью, потребуется только один или два класса из этой библиотеки.

...