21

对于我的应用程序,我需要在 Android 手机上录制来自 MIC 的音频,然后通过 TCP 将其发送到需要播放的其他 Android 手机。

我正在使用AudioRecordAudioTrack上课。这适用于文件 - 使用 将音频写入文件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);

你能看看,让我知道我在这里做错了什么吗?

谢谢,

4

3 回答 3

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,并使用字节数组而不是短裤,它会起作用。:)

于 2010-05-02T03:42:23.820 回答
2

问题出在这里:

  bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
  dataOutputStreamInstance.write(tempBuffer);

您读取bufferRead了一些字节,但您尝试将整个缓冲区写入输出流。

为了改进录制过程,您可以考虑以下几点:

  1. 启用NoiseSuppressor(自 API 16 起)
  2. 启用AcousticEchoCanceler(自 API 16 起)
  3. 增加初始缓冲区大小并应读取小于初始缓冲区大小的字节块以获得更流畅的音频流
  4. 切换到 UDP。流式传输是 UDP 作业。

这是我以前的 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);
}
于 2018-08-07T03:14:03.800 回答
1

在不知道您遇到的具体异常的情况下,很难确切知道出了什么问题。查看您用于创建的代码out1(即您的套接字代码)也将有所帮助。

您可能需要注意的是从中读取的数据量recordInstance.read();您可能无法从中获得完整大小的bufferSize数据块,因此您只需要注意将字节写入输出套接字。0bufferRead-1

于 2010-05-01T20:17:38.680 回答