Android - MediaPlayer-Puffergröße in ICS 4.0

Ich verwende einen Socket als Proxy für den MediaPlayer, damit ich MP3-Audio herunterladen und entschlüsseln kann, bevor ich es in den Socket schreibe. Dies ähnelt dem in der NPR-Nachrichten-App gezeigten Beispiel, ich verwende dies jedoch für alle Android-Versionen 2.1 - 4 atm.

NPR StreamProxy-Code -http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java

Mein Problem ist, dass die Wiedergabe für 2.1 - 2.3 schnell ist, aber in Android 4.0 ICS puffert der MediaPlayer zu viele Daten, bevor der onPrepared Listener ausgelöst wird.

Eine beispielhafte Datenmenge, die vor onPrepared () in den Socket OutputStream geschrieben wurde:

Auf SGS2 mit 2.3.4 - onPrepared () nach ~ 133920 Bytes

Auf dem Nexus S mit 4.0.4 - onPrepared () nach ~ 961930 Bytes

Dies tritt auch beim Galaxy Nexus auf.

Seltsamerweise puffert der 4.0-Emulator nicht so viele Daten wie 4.0-Geräte. Hat jemand ein ähnliches Problem mit dem MediaPlayer auf ICS?

BEARBEITEN

So schreibt der Proxy in den Socket. In diesem Beispiel handelt es sich um einen CipherInputStream, der aus einer Datei geladen wurde. Dasselbe passiert jedoch, wenn er aus der HttpResponse geladen wurde.

<code>final Socket client = (setup above)

// encrypted file input stream
final CipherInputStream inputStream = getInputStream(file);

// setup the socket output stream
final OutputStream output =  client.getOutputStream();

// Writing the header
final String httpHeader = buildHttpHeader(file.length());
final byte[] buffer = httpHeader.getBytes("UTF-8");
output.write(buffer, 0, buffer.length);

int writtenBytes = 0;
int readBytes;
final byte[] buff = new byte[1024 * 12]; // 12 KB

while (mIsRunning && (readBytes = inputStream.read(buff)) != -1) {
    output.write(buff, 0, readBytes);
    writtenBytes += readBytes;
}

output.flush();
output.close();
</code>

Die HTTP-Header, die vor dem Audio in den MediaPlayer geschrieben werden.

<code>private String buildHttpHeader(final int contentLength) {
    final StringBuilder sb = new StringBuilder();

    sb.append("HTTP/1.1 200 OK\r\n");
    sb.append("Content-Length: ").append(contentLength).append("\r\n");
    sb.append("Accept-Ranges: bytes\r\n" );
    sb.append("Content-Type: audio/mpeg\r\n");
    sb.append("Connection: close\r\n" );
    sb.append("\r\n");

    return sb.toString();
}
</code>

Ich habe mich nach alternativen Implementierungen umgesehen, aber da ich Audio verschlüsselt habe und der MediaPlayer InputStreams nicht als Datenquelle unterstützt, kann ich (glaube ich) nur einen solchen Proxy verwenden.

Auch hier funktioniert Android 2.1 - 2.3 recht gut, aber in ICS puffert der MediaPlayer eine große Menge dieser Daten, bevor er abgespielt wird.

EDIT 2:

Weitere Tests haben ergeben, dass dies auch ein Problem beim SGS2 ist, wenn es auf Android 4.0.3 aktualisiert wurde. In 4.0 hat sich die Pufferimplementierung des MediaPlayer also anscheinend erheblich geändert. Dies ist frustrierend, da die API keine Möglichkeit bietet, das Verhalten zu ändern.

EDIT 3:

Android-Bug erstellt. Bitte fügen Sie Kommentare hinzu und markieren Sie diese ebenfallshttp://code.google.com/p/android/issues/detail?id=29870

EDIT 4:

Mein Wiedergabecode ist ziemlich normal. Ich habe den start () -Aufruf auf dem MediaPlayer in meiner onPrepared () -Methode.

<code>mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mCurrentPlayer.setDataSource(url);
mCurrentPlayer.prepareAsync();
</code>

Habe es mit Prepare () und Ajacian81's empfohlenem Weg versucht, aber ohne Erfolg.

Ich sollte hinzufügen, dass kürzlich ein Google-Mitarbeiter auf meine Frage zurückkam und bestätigte, dass die Puffergröße in ICS (für HD-Inhalte) absichtlich erhöht wurde. Die API-Entwickler wurden aufgefordert, die Möglichkeit hinzuzufügen, eine Puffergröße für MediaPlayer festzulegen.

Obwohl ich glaube, dass es diese API-Änderungsanforderung schon gab, bevor ich mitgekommen bin, würde ich niemandem raten, den Atem anzuhalten.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage