Als ein Hobby-Projekt, schreibe ich einen androiden VoIP-Client. Beim Schreiben von Sprachdaten in den Socket (Vars.mediaSocket) werden die Daten oft nicht sofort über das Wifi gesendet, sondern bleiben stehen und auf einmal sendet es 20 Sekunden lang Sprache. Dann wird es wieder stehen bleiben und 30 Sekunden warten und dann 30 Sekunden Stimme senden. Das Warten ist nicht konsistent, aber nach einer Weile wird es fortlaufend Sprachdaten senden. Ich habe alles ausprobiert, von DataOutputStream zu dem Festlegen der Socket-Ausgabepuffergröße, zu dem Festlegen der sendbuffer-Größe riesig, klein und zuletzt zu dem Puffern der Sprachdaten aus seinen 32 Byte-Chunks zu allem von 128 Byte zu 32 KB.Force Java Android Socket zum Senden von Daten sofort
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);
}
Gibt es etwas, das mir fehlt? Um ein zweites Handy zu simulieren, habe ich einen anderen Client, der einfach die Sprachdaten liest, wegwirft und wieder in einer Schleife liest. Ich kann in dem simulierten zweiten Handy bestätigen, wenn das reale Handy aufhört, Sprache zu senden, der simulierte socket.read hängt, bis der echte anfängt, Stimme wieder zu senden.
Ich hoffe wirklich nicht, ein jni für die Steckdose zu schreiben, da ich nichts darüber weiß und hoffte, ich könnte die App als eine Standard-Java-App schreiben.
CASE GESCHLOSSEN: Es stellte sich heraus, dass es sich um einen Server-Side-Bug handelte, aber die vereinfachten Zurück-zur-Grundlagen-Vorschläge sind immer noch eine gute Idee.
Nicht innerhalb der Schleifen spülen. Wenn es keine Pufferung gibt, ist es sinnlos (wie in diesem Fall), und wenn es Pufferung gibt, zerstört es es. – EJP