我想用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
并提出了以下内容:(位于上面的Mike.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中与声音相关的任何东西,因此,如果我完全误解并破坏了此代码,我深表歉意(是的,我知道代码看起来很糟糕并且没有组织,但是我只是想让它正常工作)…
但是它也没有答案(唯一的答案是将其保存到文件中,但是我们俩想要的是直接将其作为字节数组进行流传输而不将其变成文件)
我所知道的:
可以使用TargetDataLine记录音频,并记录麦克风,可以使用ByteArrayOutputStream将其输出到Byte Array。
可以将音频保存到文件并通过使用AudioInputStream读取文件和使用SourceDataLine播放数据来播放。
如果我想写一个文件,我可以使用AudioSystem.write(new
AudioInputStream(microphone),AudioFileFormat.Type.WAVE,new File(“
recording.wav”);
//我已经用while循环代替了这个进行了html" target="_blank">测试行并记录良好(除非它永远不会停止,所以我不得不手动终止它),但是我不希望那样,因为输出到文件意味着不可能通过套接字将其实时发送到另一端。
我不知道/我的问题:
如何使用Java录制从麦克风录制的音频并将其传输到另一台计算机,该音频可以以尽可能少的延迟(与类似于Skype的语音聊天类似)播放。
在此先感谢您的帮助或可以为我指明正确方向的人。另外,如果有人知道更简单的方法,请也告诉我。
编辑:这是与下面相同的想法的更好的版本,将在您录制时直接播放
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
TargetDataLine microphone;
SourceDataLine speakers;
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;
int CHUNK_SIZE = 1024;
byte[] data = new byte[microphone.getBufferSize() / 5];
microphone.start();
int bytesRead = 0;
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
speakers.open(format);
speakers.start();
while (bytesRead < 100000) {
numBytesRead = microphone.read(data, 0, CHUNK_SIZE);
bytesRead += numBytesRead;
// write the mic data to a stream for use later
out.write(data, 0, numBytesRead);
// write mic data to stream for immediate playback
speakers.write(data, 0, numBytesRead);
}
speakers.drain();
speakers.close();
microphone.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
忍受我,因为这确实很粗糙,但是它可以通过扬声器播放录制的音频。
为了使其听起来更好,您将需要添加线程并优化输入/输出流。
http://www.developer.com/java/other/article.php/1579071/Java-Sound-Getting-
Started-Part-2-Capture-Using-Specified-
Mixer.htm
package audio;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
public class AudioTest {
public static void main(String[] args) {
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
TargetDataLine microphone;
AudioInputStream audioInputStream;
SourceDataLine sourceDataLine;
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;
int CHUNK_SIZE = 1024;
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, CHUNK_SIZE);
bytesRead = bytesRead + numBytesRead;
System.out.println(bytesRead);
out.write(data, 0, numBytesRead);
}
} catch (Exception e) {
e.printStackTrace();
}
byte audioData[] = out.toByteArray();
// Get an input stream on the byte array
// containing the data
InputStream byteArrayInputStream = new ByteArrayInputStream(
audioData);
audioInputStream = new AudioInputStream(byteArrayInputStream,format, audioData.length / format.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(format);
sourceDataLine.start();
int cnt = 0;
byte tempBuffer[] = new byte[10000];
try {
while ((cnt = audioInputStream.read(tempBuffer, 0,tempBuffer.length)) != -1) {
if (cnt > 0) {
// Write data to the internal buffer of
// the data line where it will be
// delivered to the speaker.
sourceDataLine.write(tempBuffer, 0, cnt);
}// end if
}
} catch (IOException e) {
e.printStackTrace();
}
// Block and wait for internal buffer of the
// data line to empty.
sourceDataLine.drain();
sourceDataLine.close();
microphone.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
}
播放音符 播放声音 录制 文字转语音
是否可以从iPhone的内置麦克风接收音频输入,并同时通过蓝牙耳机播放该音频? 我的目标是始终使用内置麦克风作为输入设备,即使输出设备是耳机,因为在我的用例中内置麦克风更方便。 当输出设备是有线耳机时,我知道如何实现我的目标,就像iPhone附带的那种。我只需插入有线耳机,并调用以下方法: 通过调用上述方法,输入设备将从有线耳机的麦克风切换到iPhone的内置麦克风,而输出设备不受影响,因此iPh
我想直播Android麦克风,可以使用VLC播放器等听到。 Playstore主要提供IP摄像头应用,但这些应用是通过内部网络实现的。我想在互联网上播放流媒体。 可能吗? 我尝试了以下代码片段,但目前不起作用: 在VLC播放器前,我试着听(媒体)- 还有别的办法吗?
问题内容: 我正在尝试通过Java访问麦克风的级别。我不需要录制任何东西,我只想知道声音水平的相对范围。 这可以实时吗? 如果这是不可能的,那么这可能会起作用:当电平超过某个值时开始记录,当电平下降到一定水平以下一段时间后停止录制四分之一秒的位并读取它的音量,如果它在阈值以下停止录音。 提前致谢 问题答案: 您可以通过Sound API访问麦克风,但不会给您简单的响度级别。您只需要捕获数据并就其声
问题内容: 我已经读了几天的Java声音API了,我无法理解。我是一个体面的程序员,只是很难理解API。 我一直在尝试从麦克风捕获音频并实时显示波形图。 我在捕捉音频时遇到麻烦,他们在教程中说要这样做,但是我似乎无法使它正常工作。 任何建议和帮助将不胜感激,逐行回答将是理想的。 谢谢,麻烦您了。 问题答案: 这将为您提供操作系统默认的设置。 要选择特定的输入设备(TargetDataLine),最
更新时间:2018-09-17 11:37:10 功能说明 高感度麦克风模块。rf13 是一款高感度麦克风模块,这里我们用该模块采集周围环境声音的大小。 硬件资源 1.ESP32Kit 开发板 2.RF13 模块 3.接线 rf13 GND 引脚接 esp32Kit GND 引脚 rf13 VCC 引脚接 esp32Kit 3.3V 引脚 rf13 AO 引脚接 esp32Kit IO34 引脚