Android - Rozmiar bufora MediaPlayer w ICS 4.0

Używam gniazda jako proxy do MediaPlayera, więc mogę pobrać i odszyfrować dźwięk mp3 przed zapisaniem go w gnieździe. Jest to podobne do przykładu pokazanego w aplikacji wiadomości NPR, ale używam tego dla wszystkich wersji Androida 2.1 - 4 atm.

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

Moim problemem jest to, że odtwarzanie jest szybkie dla 2.1 - 2.3, ale w Android 4.0 ICS MediaPlayer buforuje zbyt wiele danych przed uruchomieniem słuchacza onPrepared.

Przykładowa ilość danych zapisanych w Socket OutputStream przed onPrepared ():

Na SGS2 z 2.3.4 - onPrepared () po ~ 133920 bajtach

Na Nexusie S z 4.0.4 - onPrepared () po ~ 961930 bajtach

Dzieje się tak również w Galaxy Nexus.

Dziwnie jest, że emulator 4.0 nie buforuje tak dużo danych jak urządzenia 4.0. Czy ktoś ma podobny problem z MediaPlayerem na ICS?

EDYTOWAĆ

Oto jak proxy zapisuje w gnieździe. W tym przykładzie jest to ładowany z pliku CipherInputStream, ale to samo dzieje się, gdy jest ładowany z HttpResponse.

<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>

Nagłówki HTTP, które są zapisywane w MediaPlayer przed dźwiękiem.

<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>

Szukałem alternatywnych implementacji, ale ponieważ mam zaszyfrowane audio i MediaPlayer nie obsługuje InputStreams jako źródła danych, moją jedyną opcją (myślę ..) jest użycie proxy takiego jak to.

Ponownie działa to całkiem dobrze Android 2.1 - 2.3, ale w ICS MediaPlayer buforuje ogromną ilość tych danych przed rozpoczęciem odtwarzania.

EDYCJA 2:

Dalsze testy pokazują, że jest to również problem na SGS2 po aktualizacji do Androida 4.0.3. Wygląda więc na to, że implementacja buforowania MediaPlayera znacznie się zmieniła w wersji 4.0. Jest to frustrujące, ponieważ API nie daje możliwości zmiany zachowania.

EDYCJA 3:

Utworzono błąd Androida. Dodaj tam również komentarze i gwiazdkęhttp://code.google.com/p/android/issues/detail?id=29870

EDYTUJ 4:

Mój kod odtwarzania jest dość standardowy .. Mam wywołanie start () w MediaPlayer w mojej metodzie onPrepared ().

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

Wypróbowałem go za pomocą polecenia just prepare () i zalecanego sposobu ajacian81, ale bezskutecznie.

Powinienem dodać, że niedawno pracownik Google zwrócił się do mnie o moim pytaniu i potwierdził, że rozmiar bufora został celowo zwiększony w ICS (dla treści HD). Programiści API poprosili o dodanie możliwości ustawiania rozmiaru bufora na MediaPlayer.

Chociaż myślę, że prośba o zmianę API pojawiła się przed przyjściem, więc nie radzę nikomu wstrzymywać oddechu.

questionAnswers(2)

yourAnswerToTheQuestion