【发布时间】:2016-10-25 05:11:11
【问题描述】:
作为一个爱好项目,我正在编写一个 android voip 客户端。将语音数据写入套接字 (Vars.mediaSocket) 时,很多时候,数据不会立即通过 wifi 发送出去,而是停止,然后它会立即发送 20 秒的语音。然后它将再次停止并等待 30 秒,然后发送 30 秒的语音。等待是不一致的,但过一段时间它会立即连续发送语音数据。我已经尝试了从使用 DataOutputStream 到设置套接字输出缓冲区大小、将 sendbuffer 大小设置为大、小,最后将语音数据从 32 字节块缓冲到 128 字节到 32kb 的所有内容。
Utils.logcat(Const.LOGD, encTag, "MediaCodec encoder thread has started");
isEncoding = true;
byte[] amrbuffer = new byte[32];
short[] wavbuffer = new short[160];
int outputCounter = 0;
//setup the wave audio recorder. since it is released and restarted, it needs to be setup here and not onCreate
wavRecorder = null; //remove pointer to the old recorder for safety
wavRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLESWAV, AudioFormat.CHANNEL_IN_MONO, FORMAT, 160);
wavRecorder.startRecording();
AmrEncoder.init(0);
while(!micMute)
{
int totalRead = 0, dataRead;
while(totalRead < 160)
{//although unlikely to be necessary, buffer the mic input
dataRead = wavRecorder.read(wavbuffer, totalRead, 160 - totalRead);
totalRead = totalRead + dataRead;
}
int encodeLength = AmrEncoder.encode(AmrEncoder.Mode.MR122.ordinal(), wavbuffer, amrbuffer);
try
{
Vars.mediaSocket.getOutputStream().write(amrbuffer);
Vars.mediaSocket.getOutputStream().flush();
}
catch (IOException i)
{
Utils.logcat(Const.LOGE, encTag, "Cannot send amr out the media socket");
Utils.dumpException(tag, i);
}
我有什么遗漏吗?为了模拟第二部手机,我有另一个客户端,它只是简单地读取语音数据,将其丢弃,然后在循环中再次读取。我可以在模拟的第二部手机中确认,当真手机停止发送语音时,模拟手机的socket.read挂起,直到真手机再次开始发送语音。
我真的希望不必为套接字编写 jni,因为我对此一无所知,并希望我可以将应用程序编写为标准的 java 应用程序。
CASE CLOSED:原来是服务器端的错误,但简化回归基础的建议仍然是个好主意。
【问题讨论】:
-
不要刷新内部循环。如果没有缓冲它是没有意义的(在这种情况下),如果有缓冲它会破坏它。