Solução de problemas


Como corrigir erros "Tráfego HTTP de texto não permitido não permitido"

Esse erro ocorrerá se o app solicitar tráfego HTTP de texto não criptografado (ou seja, http:// em vez de https://) quando a Configuração de segurança de rede não permitir. Se o app for direcionado ao Android 9 (nível 28 da API) ou versões mais recentes, o tráfego HTTP de texto não criptografado será desativado pela configuração padrão.

Se o app precisar trabalhar com tráfego HTTP de texto não criptografado, use uma Configuração de segurança de rede que permita isso. Consulte a documentação de segurança de rede do Android para mais detalhes. Para ativar todo o tráfego HTTP de texto não criptografado, basta adicionar android:usesCleartextTraffic="true" ao elemento application do AndroidManifest.xml do app.

O app de demonstração do ExoPlayer usa a Configuração de segurança de rede padrão e, portanto, não permite o tráfego HTTP de texto não criptografado. É possível ativá-la usando as instruções acima.

Como corrigir os erros "SSLHandshakeException", "CertPathValidatorException" e "ERR_CERT_AUTHORITY_INVALID"

SSLHandshakeException, CertPathValidatorException e ERR_CERT_AUTHORITY_INVALID indicam um problema com o certificado SSL do servidor. Esses erros não são específicos do ExoPlayer. Consulte a documentação do SSL do Android para mais detalhes.

Por que alguns arquivos de mídia não são pesquisáveis?

Por padrão, o ExoPlayer não oferece suporte à busca em mídia em que o único método para executar operações de busca precisas é que o player verifique e indexe todo o arquivo. O ExoPlayer considera esses arquivos como inacessíveis. A maioria dos formatos de contêineres de mídia modernos inclui metadados para busca (como um índice de amostra), tem um algoritmo de busca bem definido (por exemplo, pesquisa de bissecção interpolada para Ogg) ou indica que o conteúdo tem taxa de bits constante. Operações de busca eficientes são possíveis e oferecem suporte para o ExoPlayer nesses casos.

Se você precisar fazer a busca, mas tiver mídia inacessível, sugerimos converter seu conteúdo para usar um formato de contêiner mais adequado. Para arquivos MP3, ADTS e AMR, você também pode ativar a busca presumindo que os arquivos têm uma taxa de bits constante, conforme descrito neste link.

Por que a busca é imprecisa em alguns arquivos MP3?

Os arquivos MP3 com taxa de bits variável (VBR, na sigla em inglês) não são adequados para casos de uso que exigem busca exata. Há dois motivos para isso acontecer:

  1. Para a busca exata, um formato de contêiner idealmente fornecerá um mapeamento preciso de tempo a byte em um cabeçalho. Esse mapeamento permite que um jogador mapeie um tempo de busca solicitado para o deslocamento de byte correspondente e comece a solicitar, analisar e reproduzir mídia desse deslocamento. Infelizmente, os cabeçalhos disponíveis para especificar esse mapeamento em MP3 (como os cabeçalhos XING) geralmente são imprecisos.
  2. Para formatos de contêiner que não fornecem um mapeamento preciso de tempo a byte (ou qualquer mapeamento de tempo a byte), ainda será possível realizar uma busca exata se o contêiner incluir carimbos de data/hora de amostra absolutos no stream. Nesse caso, um jogador pode mapear o tempo de busca para uma melhor estimativa do deslocamento de byte correspondente, começar a solicitar mídia desse deslocamento, analisar o primeiro carimbo de data/hora absoluto da amostra e realizar uma pesquisa binária guiada na mídia até encontrar a amostra certa. Infelizmente, o MP3 não inclui amostras absolutas de carimbos de data/hora no stream, então essa abordagem não é possível.

Por esses motivos, a única maneira de executar uma busca exata em um arquivo MP3 VBR é verificar o arquivo inteiro e criar manualmente um mapeamento de tempo para byte no player. Essa estratégia pode ser ativada usando FLAG_ENABLE_INDEX_SEEKING, que pode ser definido em um DefaultExtractorsFactory usando setMp3ExtractorFlags. Observe que ele não dimensiona bem para arquivos MP3 grandes, especialmente se o usuário tentar chegar ao fim do stream logo após iniciar a reprodução, o que exige que o player aguarde até que seja feito o download e indexe todo o stream antes de realizar a busca. No ExoPlayer, decidimos otimizar a velocidade em vez da precisão nesse caso. Portanto, FLAG_ENABLE_INDEX_SEEKING fica desativado por padrão.

Se você controla a mídia que está tocando, recomendamos usar um formato de contêiner mais adequado, como MP4. Não sabemos nos casos de uso que MP3 seja a melhor escolha de formato de mídia.

Por que a busca está lenta no meu vídeo?

Quando o player busca uma nova posição de reprodução em um vídeo, ele precisa fazer duas coisas:

  1. Carregue os dados correspondentes à nova posição de reprodução no buffer. Isso pode não ser necessário se os dados já estiverem armazenados em buffer.
  2. Desligue o decodificador de vídeo e comece a decodificar a partir do I-frame (frame-chave) antes da nova posição de reprodução, devido à codificação intraframe usada pela maioria dos formatos de compactação de vídeo. Para garantir que a busca seja precisa, ou seja, a reprodução começa exatamente na posição de busca, todos os frames entre o I-frame anterior e a posição de busca precisam ser decodificados e descartados imediatamente (sem serem mostrados na tela).

A latência introduzida por (1) pode ser atenuada aumentando a quantidade de dados armazenados em buffer na memória pelo player ou pré-armazenando em cache os dados no disco.

A latência introduzida por (2) pode ser atenuada reduzindo a precisão da busca usando ExoPlayer.setSeekParameters ou recodificando o vídeo para ter frames I mais frequentes (o que resultará em um arquivo de saída maior).

Por que alguns arquivos MPEG-TS não são reproduzidos?

Alguns arquivos MPEG-TS não contêm delimitadores de unidade de acesso (AUDs). Por padrão, o ExoPlayer depende de AUDs para detectar de maneira econômica os limites dos frames. Da mesma forma, alguns arquivos MPEG-TS não contêm frames-chave IDR. Por padrão, esses são o único tipo de frames-chave considerados pelo ExoPlayer.

O ExoPlayer vai parecer estar travado no estado de buffer quando solicitado a reproduzir um arquivo MPEG-TS sem frames-chave AUD ou IDR. Se você precisar abrir esses arquivos, faça isso usando FLAG_DETECT_ACCESS_UNITS e FLAG_ALLOW_NON_IDR_KEYFRAMES, respectivamente. Essas flags podem ser definidas em um DefaultExtractorsFactory com setTsExtractorFlags ou em um DefaultHlsExtractorFactory usando o construtor. O uso de FLAG_DETECT_ACCESS_UNITS não tem efeitos colaterais além do alto custo computacional em relação à detecção do limite de frames com base em AUD. O uso de FLAG_ALLOW_NON_IDR_KEYFRAMES pode resultar em corrupção visual temporária no início da reprodução e imediatamente após as buscas ao reproduzir alguns arquivos MPEG-TS.

Por que as legendas não são encontradas em alguns arquivos MPEG-TS?

Alguns arquivos MPEG-TS incluem faixas CEA-608, mas não os declaram nos metadados do contêiner. Por isso, o ExoPlayer não consegue detectá-los. É possível especificar manualmente qualquer faixa de legenda fornecendo uma lista de formatos de legenda esperados para o DefaultExtractorsFactory, incluindo os canais de acessibilidade que podem ser usados para identificá-las no stream MPEG-TS:

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory()
    .setTsSubtitleFormats(
      listOf(
        Format.Builder()
          .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
          .setAccessibilityChannel(accessibilityChannel)
          // Set other subtitle format info, such as language.
          .build()
      )
    )
val player: Player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory()
        .setTsSubtitleFormats(
            ImmutableList.of(
                new Format.Builder()
                    .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                    .setAccessibilityChannel(accessibilityChannel)
                    // Set other subtitle format info, such as language.
                    .build()));
Player player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

Por que alguns arquivos MP4/FMP4 são reproduzidos incorretamente?

Alguns arquivos MP4/FMP4 contêm listas de edição que regravam a linha do tempo da mídia ignorando, movendo ou repetindo listas de amostras. O ExoPlayer tem suporte parcial para aplicar listas de edição. Por exemplo, ele pode atrasar ou repetir grupos de amostras começando em uma amostra de sincronização, mas não trunca amostras de áudio nem mídias de anúncio precedente para edições que não começam em uma amostra de sincronização.

Se você perceber que parte da mídia está inesperadamente ausente ou repetida, tente configurar Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS ou FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, o que fará com que o extrator ignore completamente as listas de edição. Eles podem ser definidos em uma DefaultExtractorsFactory usando setMp4ExtractorFlags ou setFragmentedMp4ExtractorFlags.

Por que alguns streams falham com o código de resposta HTTP 301 ou 302?

Os códigos de resposta HTTP 301 e 302 indicam redirecionamento. Breves descrições podem ser encontradas na Wikipédia. Quando o ExoPlayer faz uma solicitação e recebe uma resposta com o código de status 301 ou 302, ele normalmente segue o redirecionamento e inicia a reprodução normalmente. O único caso em que isso não acontece por padrão é o de redirecionamentos entre protocolos. Um redirecionamento entre protocolos é aquele que redireciona de HTTPS para HTTP ou vice-versa (ou menos frequentemente, entre outro par de protocolos). É possível testar se um URL causa um redirecionamento entre protocolos usando a ferramenta de linha de comando wget da seguinte maneira:

wget "https://yourserver.com/test.mp3" 2>&1  | grep Location

A saída será semelhante a esta:

Location: https://second.com/test.mp3 [following]
Location: http://third.com/test.mp3 [following]

Nesse exemplo, há dois redirecionamentos. O primeiro redirecionamento é de https://yourserver.com/test.mp3 para https://second.com/test.mp3. Ambas são HTTPS e, portanto, não é um redirecionamento de protocolos cruzados. O segundo redirecionamento é de https://second.com/test.mp3 para http://third.com/test.mp3. Isso redireciona de HTTPS para HTTP, assim como um redirecionamento entre protocolos. O ExoPlayer não seguirá esse redirecionamento na configuração padrão, o que significa que a reprodução vai falhar.

Se necessário, configure o ExoPlayer para seguir redirecionamentos entre protocolos ao instanciar instâncias de DefaultHttpDataSource.Factory usadas no seu aplicativo. Saiba como selecionar e configurar a pilha de rede neste link.

Por que alguns streams falham com UnrecognizeInputFormatException?

A pergunta é relacionada a falhas de reprodução no seguinte formato:

UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.

Há duas causas possíveis para essa falha. A causa mais comum é que você está tentando reproduzir conteúdo DASH (mpd), HLS (m3u8) ou SmoothStreaming (ism, isml), mas o player tenta reproduzir como um stream progressivo. Para reproduzir esses streams, você precisa depender do respectivo módulo do ExoPlayer. Nos casos em que o URI do stream não termina com a extensão de arquivo padrão, você também pode transmitir MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 ou MimeTypes.APPLICATION_SS para setMimeType de MediaItem.Builder para especificar explicitamente o tipo de fluxo.

A segunda causa, menos comum, é que o ExoPlayer não oferece suporte ao formato de contêiner da mídia que você está tentando reproduzir. Nesse caso, a falha está funcionando conforme o esperado. No entanto, fique à vontade para enviar uma solicitação de recurso ao nosso Issue Tracker, incluindo detalhes do formato do contêiner e um stream de teste. Pesquise uma solicitação de recurso antes de enviar uma nova.

Por que setPlaybackParameters não funciona corretamente em alguns dispositivos?

Ao executar um build de depuração do app no Android M e versões anteriores, você pode ter um desempenho entrecortado, artefatos audíveis e alta utilização da CPU ao usar a API setPlaybackParameters. Isso ocorre porque uma otimização importante para essa API é desativada para builds de depuração em execução nessas versões do Android.

Esse problema afeta apenas builds de depuração. Isso não afeta os builds de lançamento, em que a otimização está sempre ativada. Portanto, as versões fornecidas aos usuários finais não serão afetadas por esse problema.

O que significam os erros "O player foi acessado na conversa errada"?

Consulte Observação sobre as linhas de execução na página de primeiros passos.

Como posso corrigir "Linha de status inesperada: ICY 200 OK"?

Esse problema poderá ocorrer se a resposta do servidor incluir uma linha de status ICY, em vez de uma que seja compatível com HTTP. As linhas de status ICY foram descontinuadas e não devem ser usadas. Portanto, se você controla o servidor, ele precisa ser atualizado para fornecer uma resposta compatível com HTTP. Se não for possível fazer isso, o uso da biblioteca OkHttp do ExoPlayer vai resolver o problema, já que ela pode processar as linhas de status ICY corretamente.

Como posso consultar se a transmissão em reprodução é uma transmissão ao vivo?

Você pode consultar o método isCurrentWindowLive do player. Além disso, você pode verificar isCurrentWindowDynamic para descobrir se a janela é dinâmica (ou seja, ainda está sendo atualizada ao longo do tempo).

Como continuo a reprodução do áudio quando meu aplicativo está em segundo plano?

Siga estas etapas para garantir a reprodução contínua do áudio quando o app estiver em segundo plano:

  1. Você precisa ter um serviço em primeiro plano em execução. Isso evita que o sistema encerre seu processo para liberar recursos.
  2. Você precisa segurar uma WifiLock e uma WakeLock. Isso garante que o sistema mantenha o rádio Wi-Fi e a CPU ativados. Isso pode ser feito facilmente se você estiver usando ExoPlayer chamando setWakeMode, que automaticamente vai adquirir e liberar os bloqueios necessários nos momentos corretos.

É importante liberar os bloqueios (se você não estiver usando setWakeMode) e interromper o serviço assim que o áudio não estiver mais sendo reproduzido.

Por que o ExoPlayer é compatível com meu conteúdo, mas a biblioteca do ExoPlayer Cast não?

É possível que o conteúdo que você está tentando reproduzir não esteja com o CORS ativado. O framework do Google Cast exige que o conteúdo tenha CORS ativado para ser reproduzido.

Por que o conteúdo não é reproduzido, mas nenhum erro aparece?

É possível que o dispositivo em que você está assistindo o conteúdo não seja compatível com um formato de amostra de mídia específico. Isso pode ser facilmente confirmado adicionando um EventLogger como listener ao player e procurando uma linha semelhante a esta no Logcat:

[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE

NO_UNSUPPORTED_TYPE significa que o dispositivo não é capaz de decodificar o formato de exemplo de mídia especificado pelo mimeType. Consulte a documentação sobre formatos de mídia do Android para informações sobre os formatos de exemplo com suporte. Como fazer com que uma biblioteca de decodificação seja carregada e usada para reprodução? também pode ser útil.

Como posso fazer com que uma biblioteca de decodificação seja carregada e usada para reprodução?

  • A maioria das bibliotecas de decodificador tem etapas manuais para verificar e criar as dependências. Portanto, siga as etapas do README para a biblioteca relevante. Por exemplo, para a biblioteca FFmpeg do ExoPlayer, é necessário seguir as instruções em libraries/decoder_ffmpeg/README.md, incluindo a transmissão de flags de configuração para ativar decodificadores para qualquer formato que você queira reproduzir.
  • Para bibliotecas que têm código nativo, verifique se você está usando a versão correta do Android NDK, conforme especificado no README, e observe se há erros durante a configuração e a criação. Você verá os arquivos .so aparecerem no subdiretório libs do caminho da biblioteca para cada arquitetura compatível depois de seguir as etapas no README.
  • Para testar a reprodução usando a biblioteca no aplicativo de demonstração, consulte Como ativar decodificadores em pacote. Consulte o README da biblioteca para ver instruções sobre como usar a biblioteca do seu app.
  • Se você estiver usando o DefaultRenderersFactory, vai encontrar uma linha de registro de informações, como "Loaded FfmpegAudioRenderer" no Logcat, quando o decodificador for carregado. Se esse atributo estiver ausente, verifique se o aplicativo tem uma dependência na biblioteca de decodificação.
  • Caso você veja registros no nível de aviso do LibraryLoader no Logcat, isso indica que houve uma falha no carregamento do componente nativo da biblioteca. Se isso acontecer, verifique se você seguiu as etapas no README da biblioteca corretamente e se nenhum erro foi gerado ao seguir as instruções.

Se você ainda tiver problemas ao usar bibliotecas de decodificação, confira o Issue Tracker da Media3 e confira os problemas recentes relevantes. Se você precisar registrar um novo problema relacionado à criação da parte nativa da biblioteca, inclua a saída completa da linha de comando das instruções README para nos ajudar a diagnosticar o problema.

Posso abrir vídeos do YouTube diretamente com o ExoPlayer?

Não, o ExoPlayer não pode reproduzir vídeos do YouTube, como URLs no formato https://www.youtube.com/watch?v=.... Em vez disso, use a API YouTube IFrame Player, que é a maneira oficial de reproduzir vídeos do YouTube no Android.

A reprodução do vídeo falha

O dispositivo pode não ser capaz de decodificar o conteúdo rápido o suficiente se, por exemplo, a taxa de bits ou a resolução do conteúdo exceder os recursos do dispositivo. Pode ser necessário usar conteúdo de qualidade mais baixa para ter um bom desempenho nesses dispositivos.

Se você tiver problemas de renderização de vídeo em um dispositivo com uma versão do Android 6.0 (nível 23 da API) até o Android 11 (nível 30 da API), principalmente ao reproduzir conteúdo protegido por DRM ou com alta taxa de frames, tente ativar a fila de buffer assíncrono.