Android - Tamanho do buffer do MediaPlayer no ICS 4.0

Eu estou usando um soquete como um proxy para o MediaPlayer para que eu possa baixar e descriptografar o áudio mp3 antes de escrevê-lo para o soquete. Isso é semelhante ao exemplo mostrado no aplicativo de notícias NPR, no entanto, estou usando isso para todas as versões do Android 2.1 - 4 atm.

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

Meu problema é que a reprodução é rápida para 2.1 - 2.3, mas no Android 4.0 ICS o MediaPlayer armazena em excesso muitos dados antes de disparar o ouvinte onPrepared.

Um exemplo de quantidade de dados gravados no Socket OutputStream antes de onPrepared ():

No SGS2 com 2.3.4 - onPrepared () após ~ 133920 bytes

No Nexus S com 4.0.4 - onPrepared () após ~ 961930 bytes

Isso também ocorre no Galaxy Nexus.

Estranhamente, o emulador 4.0 não armazena tantos dados quanto os dispositivos 4.0. Alguém experimenta um problema semelhante com o MediaPlayer no ICS?

EDITAR

Veja como o proxy está gravando no soquete. Neste exemplo, é de um CipherInputStream carregado de um arquivo, mas o mesmo ocorre quando é carregado a partir do 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>

Os cabeçalhos HTTP que são gravados no MediaPlayer antes do áudio.

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

Eu procurei implementações alternativas, mas como eu tenho áudio criptografado e o MediaPlayer não suporta InputStreams como uma fonte de dados, minha única opção (eu acho) é usar um proxy como este.

Mais uma vez, isso está funcionando muito bem Android 2.1 - 2.3, mas no ICS o MediaPlayer está armazenando uma grande quantidade desses dados antes de jogar.

EDIT 2:

Outros testes estão mostrando que este também é um problema no SGS2, uma vez atualizado para o Android 4.0.3. Portanto, parece que a implementação de buffer do MediaPlayer mudou significativamente em 4.0. Isso é frustrante, pois a API não oferece nenhuma maneira de alterar o comportamento.

EDIT 3:

Bug Android criado. Por favor, adicione comentários e estrela lá tambémhttp://code.google.com/p/android/issues/detail?id=29870

EDIT 4:

Meu código de reprodução é bastante padrão .. Eu tenho a chamada start () no MediaPlayer no meu método onPrepared ().

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

Tentei usando apenas prepare () e também a maneira recomendada de ajacian81, mas sem sucesso.

Devo acrescentar que recentemente um funcionário do Google me respondeu sobre a minha pergunta e confirmou que o tamanho do buffer foi aumentado intencionalmente no ICS (para conteúdo em HD). Foi solicitado aos desenvolvedores da API para adicionar a capacidade de definir um tamanho de buffer no MediaPlayer.

Embora eu ache que essa solicitação de mudança da API já existia antes de eu aparecer, não aconselho ninguém a segurar a respiração.

questionAnswers(2)

yourAnswerToTheQuestion