[英]Android: Streaming audio over TCP Sockets
For my app, I need to record audio from MIC on an Android phone, and send it over TCP to the other android phone, where it needs to be played. 对于我的应用程序,我需要在Android手机上录制来自MIC的音频,并通过TCP将其发送到需要播放的其他Android手机。
I am using AudioRecord
and AudioTrack
class. 我正在使用
AudioRecord
和AudioTrack
类。 This works great with a file - write audio to the file using DataOutputStream
, and read from it using DataInputStream
. 这适用于文件 - 使用
DataOutputStream
将音频写入文件,并使用DataInputStream
从中读取。
However, if I obtain the same stream from a socket instead of a File, and try writing to it, I get an exception. 但是,如果我从套接字而不是文件中获取相同的流,并尝试写入它,我会得到一个例外。
I am at a loss to understand what could possibly be going wrong. 我无法理解可能出现的问题。 Any help would be greatly appreciated.
任何帮助将不胜感激。
EDIT: The problem is same even if I try with larger buffer sizes (65535 bytes, 160000 bytes). 编辑:即使我尝试使用更大的缓冲区大小(65535字节,160000字节),问题也是一样的。
This is the code: 这是代码:
Recorder: 录音机:
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);
}
The DataOutputStream above is obtained as: 上面的DataOutputStream获得如下:
BufferedOutputStream buff = new BufferedOutputStream(out1); //out1 is the socket's outputStream
DataOutputStream dataOutputStreamInstance = new DataOutputStream (buff);
Could you please have a look, and let me know what is it that I could be doing wrong here? 请你看看,让我知道我在这里做错了什么?
Thanks, 谢谢,
I got this working, with some help, and only partially. 我得到了这个工作,有一些帮助,只有部分。
I started off with the code at http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html , changed File's streams to Socket's streams, and changed the isAvailable() to if(inputStream.read(byteArray) != -1). 我从http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html上的代码开始,将File的流更改为Socket的流,并将isAvailable()更改为if(inputStream) .read(byteArray)!= -1)。
Live streaming of audio over TCP is happening now. 现在正在通过TCP实时流式传输音频。
However, 然而,
All I hear at the other end is noise, and I am now hunting for correct set of parameters for AudioRecorder and AudioTrack - the frequency, channel config and encoding, audio source etc. 我听到的另一端是噪音,我现在正在寻找AudioRecorder和AudioTrack的正确参数集 - 频率,频道配置和编码,音频源等。
If you have any idea about this, please let me know. 如果您对此有任何疑问,请告诉我。
Thanks, 谢谢,
EDIT: It was a stupid error on my part. 编辑:这是我的一个愚蠢的错误。 In addition to all I have said above, use inputStream on player side and outputStream on recorder side, and byte arrays instead of shorts and it will work.
除了上面提到的所有内容之外,在播放器端使用inputStream,在记录器端使用outputStream,使用字节数组而不是短路,它将起作用。 :)
:)
The problem is lying here: 问题在于:
bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
dataOutputStreamInstance.write(tempBuffer);
You read bufferRead
worth of bytes but you attempt to write whole buffer to the output stream. 您读取
bufferRead
值的字节,但您尝试将整个缓冲区写入输出流。
To improve the recording process, you may consider following points: 要改善录制过程,您可以考虑以下几点:
NoiseSuppressor
(since API 16) NoiseSuppressor
(自API 16起) AcousticEchoCanceler
(since API 16) AcousticEchoCanceler
(自API 16起) Here is my setup for my previous android app: 这是我以前的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);
}
Without knowing the specific exception you're getting, it's hard to know exactly what's wrong. 如果不知道你得到的具体例外,很难确切地知道出了什么问题。 It would also help to see the code you're using to create
out1
(that is, your socket code). 查看用于创建
out1
的代码(即套接字代码)也会有所帮助。
Something you might want to pay attention to is the amount of data read from recordInstance.read()
; 您可能需要注意的是从
recordInstance.read()
读取的数据量; you might not get a whole bufferSize
-sized chunk of data out of it, so you need to take care only to write bytes 0
through bufferRead-1
to your output socket. 你可能没有得到一个完整的
bufferSize
大小的数据块,所以你只需要注意将字节0
通过bufferRead-1
写入输出套接字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.