繁体   English   中英

Android:通过TCP套接字流式传输音频

[英]Android: Streaming audio over TCP Sockets

对于我的应用程序,我需要在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);

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

谢谢,

我得到了这个工作,有一些帮助,只有部分。

我从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,使用字节数组而不是短路,它将起作用。 :)

问题在于:

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

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

要改善录制过程,您可以考虑以下几点:

  1. 启用NoiseSuppressor (自API 16起)
  2. 启用AcousticEchoCanceler (自API 16起)
  3. 增加初始缓冲区大小,应该读取比初始缓冲区的字节块,以获得更流畅的audiostream
  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);
}

如果不知道你得到的具体例外,很难确切地知道出了什么问题。 查看用于创建out1的代码(即套接字代码)也会有所帮助。

您可能需要注意的是从recordInstance.read()读取的数据量; 你可能没有得到一个完整的bufferSize大小的数据块,所以你只需要注意将字节0通过bufferRead-1写入输出套接字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM