Problema de medios de red de Android JellyBean

Tengo una aplicación que reproduce archivos MP3 que están disponibles en una URL pública. Desafortunadamente, el servidor no admite la transmisión, pero Android hace que la experiencia del usuario sea bastante aceptable.

Todo funciona bien para todas las plataformas excepto para JellyBean. Al solicitar el MP3, JB solicita un encabezado de rango 10 veces. Solo después del intento número 10 parece volver al comportamiento anterior.Parece que este problema ya reportado.

Encontré otroTan hilo donde una solución recomendada es usarTransferencia-Codificación: fragmentada encabezamiento. Pero justo debajo hay un comentario de que esto no funciona.

Por el momento no tengo control alguno para entregar encabezados de respuesta superior, pero hasta que pueda hacer eso, pensé en buscar una alternativa en el lado del cliente. (aun así, solo puedo devolver un rango de contenido que contiene índices de 0 a Content-Length - 1. Ej. Content-Range: bytes 0-3123456 / 3123457).

Lo que traté de hacer es implementar un pseudo-streaming en el lado del cliente mediante:

Abra un flujo de entrada al MP3.Decodifique los bytes entrantes utilizando JLayer. Encontré la decodificación eneste enlace.Envíe los bytes de la matriz decodificada a un Stream_mode AudioTrack ya reproducible.

El fragmento de código que hace la decodificación se puede encontrar allí, solo lo he modificado para que reciba un InputStream:

public byte[] decode(InputStream inputStream, int startMs, int maxMs) throws IOException {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);

        float totalMs = 0;
        boolean seeking = true;

        try {
            Bitstream bitstream = new Bitstream(inputStream);
            Decoder decoder = new Decoder();

            boolean done = false;
            while (!done) {
                Header frameHeader = bitstream.readFrame();
                if (frameHeader == null) {
                    done = true;
                } else {
                    totalMs += frameHeader.ms_per_frame();

                    if (totalMs >= startMs) {
                        seeking = false;
                    }

                    if (!seeking) {
                        // logger.debug("Handling header: " + frameHeader.layer_string());
                        SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);

                        if (output.getSampleFrequency() != 44100 || output.getChannelCount() != 2) {
                            throw new IllegalArgumentException("mono or non-44100 MP3 not supported");
                        }

                        short[] pcm = output.getBuffer();
                        for (short s : pcm) {
                            outStream.write(s & 0xff);
                            outStream.write((s >> 8) & 0xff);
                        }
                    }

                    if (totalMs >= (startMs + maxMs)) {
                        done = true;
                    }
                }
                bitstream.closeFrame();
            }

            return outStream.toByteArray();
        } catch (BitstreamException e) {
            throw new IOException("Bitstream error: " + e);
        } catch (DecoderException e) {
            throw new IOException("Decoder error: " + e);
        }
    }

Estoy solicitando los bytes decodificados en partes de tiempo: comenzando con (0, 5000), así que tendré una matriz más grande para jugar al principio, luego estoy solicitando las siguientes matrices de bytes que se extienden por un segundo: (5000, 1000), ( 6000, 1000), (7000, 1000), etc.

La decodificación es lo suficientemente rápida y se realiza en otro subproceso y una vez que una matriz de bytes decodificada está disponible, estoy usando una cola de bloqueo para escribirla en la pista de audio que se está reproduciendo en otro hilo.

El problema es que la reproducción no es suave ya que los fragmentos no son continuos en una pista (cada fragmento es continuo, pero agregado en el AudioTrack da como resultado una reproducción descuidada).

Para concluir:

Si se ha topado con este problema de JellyBean, ¿cómo lo resolvió?Si alguno de ustedes intentó mi enfoque, ¿qué estoy haciendo mal en el código anterior? Si esta es la solución que usaste, puedo publicar el resto del código.

¡Gracias!

Respuestas a la pregunta(2)

Su respuesta a la pregunta