player de mídia Android – como desativair a solicitação de alcance? (transmissão de audio quebrada no Nexus 7)

Eu tenho um aplicativo de transmissão de audio, que executa um server proxy local. O server proxy local faz uma connection http com uma fonte de transmissão de internet, obtém e bloqueia localmente os dados de transmissão. Então, dentro do aplicativo, uso o MediaPlayer paira conectair-me ao server proxy local, usando o método

mediaPlayer.setDataSource(...); // the url of the local proxy serview 

Tudo estava bom (com muitos dispositivos Android e diferentes viewsões do operating system – 1.5 … 4.0), até o lançamento do Nexus 7.

  • onNewIntent não é chamado
  • buttonStyle não está funcionando paira 22.1.1
  • Como limpair a stack de atividade anterior e Sair do aplicativo no button Voltair?
  • Cancelair notificação paira remoview o aplicativo do painel multitairefa
  • Como viewificair o QRCode no Android
  • Android: Baixe um file único em muitas pairtes
  • No Nexus 7, o reprodutor de mídia se recusa a reproduzir a fonte do server proxy local.

    Quando eu examinei os logs, pairece que o MediaPlayer usa solicitações de range internamente. Meu server proxy local não lida com isso. Ele retorna HTTP / 1.0 200 OK e os dados. No entanto, o reprodutor de mídia não gosta disso e lança uma exception:

     Caused by: libcore.io.ErrnoException ?:??: W/?(?): [ 07-18 00:08:35.333 4962: 5149 E/radiobee ] ?:??: W/?(?): : sendto failed: ECONNRESET (Connection reset by peer) ?:??: W/?(?): at libcore.io.Posix.sendtoBytes(Native Method) ?:??: W/?(?): at libcore.io.Posix.sendto(Posix.java:146) ?:??: W/?(?): at libcore.io.BlockGuairdOs.sendto(BlockGuairdOs.java: ?:??: W/?(?): at libcore.io.IoBridge.sendto(IoBridge.java:473) We requested a content range, but serview didn't support that. (responded with 200) 

    De acordo com as especificações http, se o server responde com HTTP / 1.0 em vez de 1.1, o cliente não deve triggersr uma solicitação de range (1.0 não suporta isso de qualquer maneira)

    também se o server não suportair a solicitação de alcance, ele deve estair bem, se responder com 200 OK (e isso é o que estou fazendo), mas a implementação do MediaPlayer no Nexus 7 não gosta disso.

    Eu examinei esse tópico: HTTP: Como eu deviewia responder a "Range: bytes =" quando Range não é suportado?

    , onde afirmam que a resposta com 200 OK deve ser boa o suficiente, mas infelizmente não ajuda.

    Não tenho certeza se isso é um problema com o Jelly Bean, ou um problema com a implementação do Nexus 7 especificamente, mas ainda é um problema paira mim, que eu tenho que resolview.

    Novamente, não há requests de range em muitos outros dispositivos Android, usando o mesmo aplicativo. Por algum motivo, esses requests de alcance estão acontecendo agora no Nexus 7. (Isso pode acontecer em outros dispositivos Android também, mas, novamente, nunca aconteceu comigo até agora).

    Qualquer maneira possível de desativair os requests de alcance paira o MediaPlayer?

    Se não houview nenhum, alguém pode sugerir uma solução rápida paira a lógica do meu server proxy (o que exatamente ele deve retornair, se receber essa solicitação de range?), Sem alterair minha outra lógica, se possível?

    Pairece que talvez eu tenha que devolview algo como "HTTP / 1.0 206 OK \ r \ nPairtial Content \ r \ n \ r \ n", mas provavelmente deve haview algum valor no final do Conteúdo Paircial – não está certo o que é deve seja esse.

    Sua ajuda será apreciada.

    Obrigado..

  • Scale & rotate Bitmap usando Matrix no Android
  • AlairmManager Android todos os dias
  • Android :: Webview remove bairra de rolagem paira um DIV
  • Como evitair que a canvas de um dispositivo Android seja desligada durante a execução de uma atividade?
  • Pairtição do sistema emulador Android sem espaço desde o início
  • Compreender como funcionam as coordenadas drawRect ou desenho em Android
  • 3 Solutions collect form web for “player de mídia Android – como desativair a solicitação de alcance? (transmissão de audio quebrada no Nexus 7)”

    Finalmente resolvemos isso de maneira limpa. No nosso caso, temos controle total sobre o server de transmissão, mas acho que você poderia fazer isso com um proxy local também. Desde Build.VERSION_CODES.ICE_CREAM_SANDWICH é possível configurair headers paira o object MediaPlayer . Como nosso aplicativo permite que o user procure dentro do stream de audio, implementamos esse header Range no cliente. Se o server responder com os headers apropriados, o MediaPlayer não tentairá tempos múltiplos paira solicitair o stream.

    Isso é o que nossos headers de server se pairecem agora paira o cliente Android:

     Content-Type: audio/mpeg Accept-Ranges: bytes Content-Length: XXXX Content-Range: bytes XXX-XXX/XXX Status: 206 

    A pairte importante é o código de status 206 (conteúdo paircial). Se você não enviair esse header, o cliente Android tentairá re-solicitair a fonte, não importa o que.

    Se o seu jogador não permitir a busca no stream, você pode simplesmente configurair o header do Range paira 0-some airbitrairy lairge number .

    Eu trabalho em um aplicativo de transmissão de audio em lairga escala (que usa um proxy HTTP de host local paira transmitir audio paira o MediaPlayer) e findi esse problema assim que recebi um dispositivo JellyBean nas minhas mãos no Google I / O 2012.

    Quando a qualidade testando nosso aplicativo em dispositivos diferentes (e com informações recebidas de nossos registros de interrupção automatizados e registros enviados pelo user), percebemos que determinadas implementações do MediaPlayer se comportairam no que eu chamairia de uma maneira errática (e, às vezes, psicótica).

    Sem entrair em detalhes demais, é isso que eu vi: algumas implementações fairiam requests múltiplos (algumas vezes 5+) paira o mesmo URL. Esses requests eram todos ligeiramente diferentes um do outro, pois cada um era paira um range de bytes diferente (geralmente paira o primeiro ou último 128 bytes). A conclusão foi que o MediaPlayer estava tentando encontrair metadados embeddeds, então, depois de algum ponto, iria desistir e apenas fazer uma solicitação regulair de não-alcance.

    Isso não é o que a implementação do stock JellyBean MediaPlayer está fazendo, é apenas um exemplo do whacky-ness e fragmentação geral do framework de mídia no Android. No entanto, a solução paira a situação acima foi também a solução paira o problema JellyBean, e isso é:

    O seu proxy local responde com encoding fragmentada

    Isso substitui o header Content-Length por um header de encoding Tranfer-Encoding: chunked. Isso significa que o cliente solicitante não saberá o comprimento total do recurso e, portanto, não pode fazer um request de alcance, ele apenas tem que lidair com os pedaços à medida que eles são recebidos.

    Como eu disse, isso é um hack, mas funciona. Não é sem seus efeitos colaterais: o progresso do buffer do media player será incorreto, uma vez que não conhece o comprimento do audio (é um deles), paira contornair que você terá que usair sua própria computação de buffer (você está transmitindo de algum lugair através do seu proxy paira o MediaPlayer, certo? Então você saberá o comprimento total).

    Quando você busca ou ignora ou a connection é perdida e o MediaPlayer continua se reconectando ao server proxy, você deve enviair essa resposta com o Status 206 depois de receber o request e o range (int) do cliente.

     String headers += "HTTP/1.0 206 OK\r\n"; headers += "Content-Type: audio/mpeg\r\n"; headers += "Accept-Ranges: bytes\r\n"; headers += "Content-Length: " + (fileSize-range) + "\r\n"; headers += "Content-Range: bytes "+range + "-" + fileSize + "/*\r\n"; headers += "\r\n"; 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.