对于我的应用程序,我需要在Android手机上录制来自MIC的音频,并通过TCP将其发送到需要播放的其他Android手机。
我正在使用AudioRecord
和AudioTrack
类。这适用于文件 - 使用DataOutputStream
将音频写入文件,并使用DataInputStream
从中读取。
但是,如果我从套接字而不是文件中获取相同的流,并尝试写入它,我会得到一个例外。
我无法理解可能出现的问题。任何帮助将不胜感激。
编辑:即使我尝试使用更大的缓冲区大小(65535字节,160000字节),问题也是一样的。
这是代码:
录像机:
int bufferSize = AudioRecord.getMinBufferSize(11025, , AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
byte[] tempBuffer = new byte[bufferSize];
recordInstance.startRecording();
while (/*isRecording*/) {
bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
dataOutputStreamInstance.write(tempBuffer);
}
上面的DataOutputStream获取为:
BufferedOutputStream buff = new BufferedOutputStream(out1); //out1 is the socket's outputStream
DataOutputStream dataOutputStreamInstance = new DataOutputStream (buff);
请你看看,让我知道我在这里做错了什么?
谢谢,
答案 0 :(得分:8)
我得到了一些帮助,但只是部分帮助。
我开始使用http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html处的代码,将File的流更改为Socket的流,并将isAvailable()更改为if(inputStream.read(byteArray)!= -1)。
现在正在通过TCP实时播放音频。
<强>然而,强>
我听到的另一端是噪音,我现在正在为AudioRecorder和AudioTrack寻找正确的参数集 - 频率,频道配置和编码,音频源等。
如果您对此有任何疑问,请告诉我。
谢谢,
编辑: 这对我来说是一个愚蠢的错误。 除了上面提到的所有内容之外,在播放器端使用inputStream,在记录器端使用outputStream,使用字节数组而不是短路,它将起作用。 :)
答案 1 :(得分:2)
问题出在这里:
bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
dataOutputStreamInstance.write(tempBuffer);
您读取了bufferRead
个字节,但是您尝试将整个缓冲区写入输出流。
为改进记录过程,您可以考虑以下几点:
NoiseSuppressor
(自API 16开始)AcousticEchoCanceler
(自API 16开始)这是我以前的android应用程序的设置:
// Calculate minimum buffer size
int minBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
// Initialize AudioRecord for getting audio from device
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 4);
if (API > API 16) {
if (NoiseSuppressor.isAvailable()) {
NoiseSuppressor.create(recorder.getAudioSessionId()).setEnabled(true);
}
if (AcousticEchoCanceler.isAvailable()) {
AcousticEchoCanceler.create(recorder.getAudioSessionId()).setEnabled(true);
}
}
....
byte[] tempBuffer = new byte[minBufferSize];
while (/*isRecording*/) {
bufferRead = recordInstance.read(tempBuffer, 0, minBufferSize);
dataOutputStreamInstance.write(tempBuffer, 0, bufferRead);
}
答案 2 :(得分:1)
如果不知道你得到的具体例外,很难确切地知道出了什么问题。查看用于创建out1
的代码(即套接字代码)也会有所帮助。
您可能需要注意的是从recordInstance.read()
读取的数据量;您可能无法获得整个bufferSize
大小的数据块,因此您只需要注意将0
到bufferRead-1
的字节写入输出套接字。