Я хочу сделать живую программу для голосового общения на Java, но я ничего не знаю о записи/воспроизведении звука на Java, поэтому с помощью Google я думаю, что мне удалось записать с моего микрофона на массив байтов с помощью следующее:
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
TargetDataLine microphone;
try{
microphone = AudioSystem.getTargetDataLine(format);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
microphone = (TargetDataLine)AudioSystem.getLine(info);
microphone.open(format);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int numBytesRead;
byte[] data = new byte[microphone.getBufferSize()/5];
microphone.start();
int bytesRead =0;
try{
while(bytesRead<100000){ //Just so I can test if recording my mic works...
numBytesRead = microphone.read(data, 0, data.length);
bytesRead = bytesRead + numBytesRead;
// System.out.println(bytesRead);
out.write(data, 0, numBytesRead);
}
catch(Exception e){
e.printStackTrace();
}
microphone.close();
catch(LineUnavailibleException e){
e.printStackTrace();
}
Итак, к моему пониманию, если я вызываю out.toByteArray();, я должен был получить байтовый массив звука, который я только что записал из своего микрофона. (У меня не было ошибок при выполнении вышеуказанного, но у меня нет способа доказать, действительно ли он записан, потому что я не хочу выводить его в файл и не делал этого)
Теперь, если приведенное выше верно, тогда ниже я столкнулся с моей проблемой: Я хочу теперь воспроизвести массив байтов, который я только что создал... (В моей реальной программе я отправил байты в свою "приемную программу" через Java-сокет, который я уже смог сделать, но прямо сейчас Я просто хочу создать небольшую программу, которая записывает микрофон и воспроизводит его). Чтобы воспроизвести звуковую информацию из массива байтов, я последовал за этим: http://www.wikijava.org/wiki/Play_a_wave_sound_in_Java И придумал следующее: (это расположено сразу после microphone.close() из вышеперечисленного)
try{
DataLine.Info info2 = DataLine.Info(SourceDataLine.class, format);
SourceDataLine dataLine = (SourceDataLine)AudioSystem.getLine(info2);
int bufferSize = 2200;
soundLine.open(format, bufferSize);
soundLine.start();
AudioInputStream audioInputStream = null;
InputStream input = new ByteArrayInputStream(out.toByteArray());
audioInputStream = AudioSystem.getAudioInputStream(input);
...
Остальное довольно много копируется с playSound.java по этой ссылке: http://www.wikijava.org/wiki/Play_a_wave_sound_in_Java
Когда я запускаю вышеуказанный код... Запись, похоже, работает нормально, но я получаю следующую ошибку:
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
для этой строки audioInputStream = AudioSystem.getAudioInputStream(input);
Из моих ограниченных знаний я предполагаю это, потому что я каким-то образом испортил метод записи, мне нужен какой-то "заголовок аудиоформата"? https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ (я предположил, что мне не понадобится что-то подобное, потому что я никогда не сохранялся в файле и просто сохранял все как байтовый массив), или я просто совершенно неправильно понял, как java AudioInputStream считывает и анализирует данные...
Это мой первый опыт работы с любыми звуковыми вещами на Java, поэтому я извиняюсь, если полностью недопонимаю и разбиваю этот код (да, я знаю, что код выглядит довольно плохо и неорганизован, но я просто хочу заставить его работать)... Я попробовал несколько поисков в Google/StackOverflow и смог найти очень похожий вопрос:
java байт для воспроизведения звука
но он также остался без ответа (единственный ответ состоял в том, чтобы сохранить его в файле, но мы оба хотим передать его непосредственно в виде байтового массива без его создания)
Что я знаю:
Аудио можно записывать с помощью TargetDataLine и записывать микрофон, который может быть выведен в массив байтов, используя ByteArrayOutputStream
Аудио можно сохранить в файл и воспроизвести с помощью AudioInputStream для чтения файла и SourceDataLine для воспроизведения данных.
Если бы я хотел написать файл, я мог бы использовать AudioSystem.write(новый AudioInputStream (микрофон), AudioFileFormat.Type.WAVE, новый файл ( "record.wav" );//Я протестировал это, заменив while петля с этой строкой, и она записана отлично (за исключением того, что она никогда не остановится, поэтому мне пришлось вручную ее завершить), но я не хочу этого, потому что вывод в файл означает, что невозможно будет отправить его через сокет на другую сторону в режиме реального времени.
Что я не знаю/Мой вопрос:
Как записывать и передавать аудио, записанные с микрофона на другой компьютер, который можно воспроизводить с минимальной задержкой (в значительной степени похожим на голосовой чат, похожий на Skype) на Java.
Заранее благодарим за помощь или кого-то, кто может указать мне в правильном направлении. Также, если кто-то знает более простой метод, то, пожалуйста, скажите мне это также.