Risoluzione dei problemi


Correzione del messaggio "Traffico HTTP in chiaro non consentito" errori

Questo errore si verifica se la tua app richiede traffico HTTP con testo in chiaro (ovvero http:// anziché https://) quando la configurazione della sicurezza di rete funziona non lo permetta. Se la tua app ha come target Android 9 (livello API 28) o versioni successive, inserisci il testo in chiaro. Il traffico HTTP è disattivato per la configurazione predefinita.

Se la tua app deve funzionare con traffico HTTP in chiaro, devi utilizzare un la configurazione della sicurezza della rete che lo consente. Guarda le app per Android documentazione sulla sicurezza di rete per maggiori dettagli. Per attivare tutto il traffico HTTP con testo in chiaro, puoi semplicemente aggiungere android:usesCleartextTraffic="true" all'elemento application della tabella AndroidManifest.xml.

L'app demo ExoPlayer utilizza la configurazione di sicurezza di rete predefinita, quindi non consente il traffico HTTP con testo in chiaro. Puoi abilitarlo seguendo le istruzioni in alto.

Correzione di "SSLHandshakeException", "CertPathValidatorException" e "ERR_CERT_AUTHORITY_INVALID" errori

SSLHandshakeException, CertPathValidatorException e ERR_CERT_AUTHORITY_INVALID indicano tutti un problema con l'SSL del server certificato. Questi errori non sono specifici di ExoPlayer. Consulta Documentazione SSL di Android per ulteriori informazioni.

Perché non è possibile cercare alcuni file multimediali?

Per impostazione predefinita, ExoPlayer non supporta la ricerca nei contenuti multimediali dove l'unico metodo per operazioni di ricerca accurate è che il player esamini e indicizzi l'intero file. ExoPlayer considera questi file come non cercabili. Media più moderni includono metadati per la ricerca (come un indice di esempio), hanno un un algoritmo di ricerca ben definito (ad esempio, la ricerca in bisezione interpolata di Ogg). indicano che i contenuti hanno una velocità in bit costante. Le operazioni di ricerca efficienti sono possibili e supportati da ExoPlayer in questi casi.

Se hai bisogno di cercare contenuti multimediali non disponibili, ti consigliamo di convertire contenuti con un formato contenitore più appropriato. Per i file MP3, ADTS e AMR, puoi anche abilitare la ricerca supponendo che i file abbiano una costante velocità in bit, come descritto qui

Perché la ricerca non è precisa in alcuni file MP3?

I file MP3 con velocità in bit variabile (VBR) sono fondamentalmente inadatti per i casi d'uso che richiedono una ricerca esatta. Questo può accadere per due motivi:

  1. Per la ricerca esatta, un formato container fornirà idealmente un valore il mapping time-to-byte in un'intestazione. Questa mappatura consente a un player di mappare di ricerca all'offset di byte corrispondente e iniziare a richiedere, l'analisi e la riproduzione dei contenuti multimediali da quell'offset. Le intestazioni disponibili per che specifica questo mapping in MP3 (come le intestazioni XING) sono, purtroppo, spesso impreciso.
  2. Per i formati container che non forniscono una mappatura time-to-byte precisa (oppure qualsiasi mapping time-to-byte), è comunque possibile eseguire una cerca se il container include timestamp assoluti di esempio nello stream. Nella questo caso un giocatore può mappare il tempo di ricerca a una migliore ipotesi del corrispondente byte, inizia a richiedere contenuti multimediali da quell'offset, analizza il primo timestamp assoluto di esempio ed eseguire in modo efficace una ricerca binaria guidata nei contenuti multimediali finché non trova il campione giusto. Purtroppo l'MP3 non includere timestamp assoluti di esempio nello stream, quindi questo approccio possibile.

Per questi motivi, l'unico modo per eseguire una ricerca esatta in un file MP3 VBR è eseguire la scansione dell'intero file e generare manualmente un mapping time-to-byte nel un player. Questa strategia può essere attivata utilizzando FLAG_ENABLE_INDEX_SEEKING, che può essere impostato su un DefaultExtractorsFactory utilizzando setMp3ExtractorFlags Tieni presente che non si adatta bene ai file MP3 di grandi dimensioni, in particolare se l'utente cerca di avvicinarsi alla fine dello stream in un istante dopo l'avvio della riproduzione, il che richiede che il player attenda il completamento del download e indicizzato l'intero flusso prima di eseguire la ricerca. In ExoPlayer, abbiamo deciso di ottimizzare la velocità piuttosto che la precisione. FLAG_ENABLE_INDEX_SEEKING è quindi disattivato per impostazione predefinita.

Se controlli i contenuti multimediali che stai riproducendo, ti consigliamo vivamente di utilizzare un formato container appropriato, ad esempio MP4. Non siamo a conoscenza di casi d'uso dove MP3 è la scelta migliore per i media.

Perché la ricerca nel mio video è lenta?

Quando il player punta in una nuova posizione di riproduzione in un video, deve eseguire due operazioni: cose:

  1. Carica nel buffer i dati corrispondenti alla nuova posizione di riproduzione (potrebbe non essere necessario se questi dati sono già presenti nel buffer).
  2. Esegui il flush del decodificatore video e inizia la decodifica dall'I-frame (frame chiave) prima di la nuova posizione di riproduzione, grazie alla codifica intra-frame utilizzata dalla maggior parte dei video formati di compressione. Per garantire che la ricerca sia accurata, ovvero la riproduzione inizia esattamente dalla posizione di ricerca), a tutti i fotogrammi l'I-frame precedente e la posizione di ricerca devono essere decodificati e eliminati (senza essere mostrati sullo schermo).

La latenza introdotta dalla (1) può essere mitigata aumentando la quantità di dati memorizzati nel buffer in memoria dal player o memorizzazione nella cache pre-memorizzazione dei dati su disco.

La latenza introdotta dalla (2) può essere mitigata riducendo la precisione della ricerca utilizzando ExoPlayer.setSeekParameters o ricodificando il video avere I-frame più frequenti (il che produrrà un file di output più grande).

Perché alcuni file MPEG-TS non vengono riprodotti?

Alcuni file MPEG-TS non contengono delimitatori di unità di accesso (AUD). Per impostazione predefinita, ExoPlayer si affida agli AUD per rilevare in modo economico i confini dei frame. Analogamente, alcune I file MPEG-TS non contengono fotogrammi chiave IDR. Per impostazione predefinita, questi sono gli unici tipi di fotogrammi chiave considerati da ExoPlayer.

ExoPlayer risulta bloccato nello stato di buffering quando viene richiesto di riprodurre un File MPEG-TS privo di fotogrammi chiave AUD o IDR. Se devi riprodurre questi file, puoi farlo utilizzando FLAG_DETECT_ACCESS_UNITS e FLAG_ALLOW_NON_IDR_KEYFRAMES rispettivamente. Questi flag possono essere impostati su una DefaultExtractorsFactory con setTsExtractorFlags o su una DefaultHlsExtractorFactory utilizzando costruttore. L'utilizzo di FLAG_DETECT_ACCESS_UNITS non ha alcun effetto collaterale di calcolo rispetto al rilevamento dei confini del frame basato su AUD. Uso di FLAG_ALLOW_NON_IDR_KEYFRAMES potrebbe causare una corruzione temporanea dell'immagine del all'inizio della riproduzione e subito dopo effettua una ricerca quando vengono riprodotti alcuni file MPEG-TS.

Perché i sottotitoli non si trovano in alcuni file MPEG-TS?

Alcuni file MPEG-TS includono tracce CEA-608 ma non le dichiarano nel dei metadati del container, quindi ExoPlayer non è in grado di rilevarli. Puoi eseguire manualmente specificare eventuali tracce di sottotitoli fornendo un elenco di formati dei sottotitoli codificati al DefaultExtractorsFactory, inclusa l'accessibilità canali che possono essere utilizzati per identificarli nello 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();

Perché alcuni file MP4/FMP4 non vengono riprodotti correttamente?

Alcuni file MP4/FMP4 contengono elenchi di modifica che riscrivono la sequenza temporale dei file multimediali saltare, spostare o ripetere elenchi di campioni. ExoPlayer ha un supporto parziale per applicare gli elenchi di modifica. Ad esempio, può ritardare o ripetere gruppi di campioni avviando un campione di sincronizzazione, ma i campioni audio o i relativi audio non vengono troncati contenuti multimediali pre-roll per le modifiche che non vengono avviate su un campione di sincronizzazione.

Se noti che una parte dei contenuti multimediali è inaspettatamente mancante o ripetuta, prova a impostare Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS o FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, che causerà l'estrattore per ignorare completamente gli elenchi di modifica. Queste possono essere impostate su una DefaultExtractorsFactory tramite setMp4ExtractorFlags oppure setFragmentedMp4ExtractorFlags

Perché alcuni flussi hanno esito negativo con il codice di risposta HTTP 301 o 302?

I codici di risposta HTTP 301 e 302 indicano entrambi il reindirizzamento. Brevi descrizioni disponibile su Wikipedia. Quando ExoPlayer effettua una richiesta e riceve un con il codice di stato 301 o 302, di solito segue il reindirizzamento e avviare la riproduzione normalmente. L'unico caso in cui questo non avviene per impostazione predefinita riguarda i reindirizzamenti multiprotocollo. Un reindirizzamento multiprotocollo è un reindirizzamento da HTTPS a HTTP o viceversa (o meno comunemente, tra altre coppie di protocolli). Puoi verificare se un URL causa un reindirizzamento multiprotocollo utilizzando lo strumento a riga di comando wget come segue:

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

L'output dovrebbe essere simile al seguente:

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

In questo esempio sono presenti due reindirizzamenti. Il primo reindirizzamento proviene da Da https://yourserver.com/test.mp3 a https://second.com/test.mp3. Entrambi sono HTTPS, pertanto non si tratta di un reindirizzamento multiprotocollo. Il secondo reindirizzamento proviene Da https://second.com/test.mp3 a http://third.com/test.mp3. Questo reindirizza da HTTPS a HTTP, così come il reindirizzamento multiprotocollo. ExoPlayer non segui questo reindirizzamento nella sua configurazione predefinita, impedendo la riproduzione.

Se necessario, puoi configurare ExoPlayer in modo che segua i reindirizzamenti multiprotocollo quando crei un'istanza delle istanze DefaultHttpDataSource.Factory utilizzate nel tuo un'applicazione. Scopri di più su come selezionare e configurare lo stack di rete qui

Perché alcuni stream hanno esito negativo con Un knownInputFormatException?

Questa domanda riguarda gli errori di riproduzione nel seguente formato:

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

Le possibili cause di questo errore sono due. La causa più comune è che stai tentando di riprodurre DASH (mpd), HLS (m3u8) o smoothStreaming (ism, isml) ma il player tenta di riprodurli come stream progressivo. Per riprodurre tali devi dipendere dal rispettivo modulo ExoPlayer. Nei casi in cui l'URI dello stream non termina con l'estensione standard del file, puoi anche MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 o Da MimeTypes.APPLICATION_SS a setMimeType di MediaItem.Builder per esplicitamente e specificare il tipo di stream.

La seconda causa meno comune è che ExoPlayer non supporta il container formato dei contenuti multimediali che stai tentando di riprodurre. In questo caso, l'errore è funzionino come previsto, tuttavia non esitare a inviare una richiesta di funzionalità ai nostri tracker dei problemi, che include dettagli sul formato del contenitore e uno stream di prova. Cerca una richiesta di funzionalità esistente prima di inviarne una nuova.

Perché setPlaybackParameters non funziona correttamente su alcuni dispositivi?

Quando esegui una build di debug della tua app su Android M e versioni precedenti, puoi: in caso di prestazioni discontinua, artefatti udibili e utilizzo elevato della CPU utilizzando l'API setPlaybackParameters. Il motivo è che un'ottimizzazione che è importante per questa API sia disabilitata per le build di debug in esecuzione su questi tutte le versioni di Android.

È importante notare che questo problema riguarda solo le build di debug. Non influisce sulle build delle release, per le quali l'ottimizzazione è sempre abilitata. Di conseguenza le release fornite agli utenti finali non dovrebbero essere interessate da questo problema.

Cosa significa "Si accede al player sul thread sbagliato"? significano errori.

Consulta la sezione Nota sull'organizzazione in thread nella pagina iniziale.

Come posso risolvere il problema "Riga dello stato imprevisto: ICY 200 OK"?

Questo problema può verificarsi se la risposta del server include una riga di stato ICY, anziché uno conforme a HTTP. Le righe di stato ICY sono obsolete e non dovrebbe essere usato, quindi se controlli il server devi aggiornarlo per fornire una risposta conforme a HTTP. Se non riesci a farlo, utilizza La libreria OkHttp ExoPlayer risolve il problema, poiché è in grado di gestire ICY le righe di stato in modo corretto.

Come posso chiedere se lo stream in riproduzione è un live streaming?

Puoi eseguire una query sul metodo isCurrentWindowLive del player. Inoltre, puoi controllare isCurrentWindowDynamic per scoprire se la finestra è dinamica (ovvero i contenuti vengono sempre aggiornati nel tempo).

Come faccio a riprodurre l'audio quando la mia app viene riprodotta in background?

Segui questi passaggi per garantire la riproduzione continua dell'audio quando l'app è attiva sullo sfondo:

  1. Devi disporre di un servizio in primo piano in esecuzione. Questo impedisce al sistema l'interruzione del processo per liberare risorse.
  2. Devi contenere una WifiLock e un WakeLock. che assicurano di sistema mantiene attivi la radio Wi-Fi e la CPU. Questa operazione può essere eseguita facilmente ExoPlayer chiamando setWakeMode, che verrà attivato automaticamente di acquisire e rilasciare i blocchi richiesti nei momenti corretti.

È importante rilasciare i blocchi (se non usi setWakeMode) e interrompere l'operazione. il servizio non appena l'audio non viene più riprodotto.

Perché ExoPlayer supporta i miei contenuti ma la libreria Cast di ExoPlayer no?

È possibile che i contenuti che stai tentando di riprodurre non siano CORS abilitato. Il framework Cast richiede l'attivazione di CORS per i contenuti in ordine di riprodurlo.

Perché i contenuti non vengono riprodotti ma non vengono rilevati errori?

È possibile che il dispositivo su cui stai riproducendo i contenuti non Supporta un formato di esempio multimediale specifico. Questa operazione può essere facilmente confermata aggiungendo un EventLogger come ascoltatore del player e alla ricerca di una riga simile a questo in Logcat:

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

NO_UNSUPPORTED_TYPE significa che il dispositivo non è in grado di decodificare i contenuti multimediali formato di esempio specificato da mimeType. Scopri i formati multimediali Android documentazione per informazioni sui formati di esempio supportati. Come posso una libreria di decodifica da caricare e utilizzare per la riproduzione.

Come faccio a far caricare una libreria di decodifica e utilizzarla per la riproduzione?

  • La maggior parte delle librerie decoder prevede passaggi manuali per eseguire il check-out e creare le dipendenze, assicurati di aver seguito i passaggi nel file README della libreria pertinente. Ad esempio, per la libreria FFmpeg ExoPlayer è necessario seguire la macro in libraries/decoder_ffmpeg/README.md, tra cui il passaggio per abilitare i decoder per tutti i formati che vuoi riprodurre.
  • Per le librerie che contengono codice nativo, assicurati di utilizzare il codice corretto dell'Android NDK come specificato nel file README e cercate vengono visualizzati durante la configurazione e la creazione. Dovresti vedere .so vengono visualizzati nella sottodirectory libs del percorso della libreria per ogni architettura supportata dopo aver seguito i passaggi nel file README.
  • Per provare la riproduzione utilizzando la libreria nell'applicazione demo, consulta abilitando i decoder in bundle. Controlla il file README per la libreria per istruzioni sull'uso della raccolta dalla tua app.
  • Se utilizzi DefaultRenderersFactory, dovresti vedere un livello di informazioni riga di log simile a "Loaded FfmpegAudioRenderer" in Logcat quando viene caricato il decoder. Se manca, assicurati che l'applicazione abbia una dipendenza dal server libreria di decodifica.
  • Se vedi log a livello di avviso da LibraryLoader in Logcat, questo indica che il caricamento del componente nativo della libreria non è riuscito. Se questo verifica di aver seguito correttamente i passaggi nel file README della libreria e che non vengano generati errori mentre segui le istruzioni.

Se continui a riscontrare problemi nell'utilizzo delle librerie di decodifica, consulta Tracker dei problemi Media3 per eventuali problemi recenti pertinenti. Se devi inviare un ticket di assistenza un nuovo problema relativo allo sviluppo della parte nativa della libreria, includi l'output della riga di comando completo dell'esecuzione di istruzioni README, per aiutarci diagnosticare il problema.

Posso riprodurre i video di YouTube direttamente con ExoPlayer?

No, ExoPlayer non può riprodurre video da YouTube, come URL nel formato https://www.youtube.com/watch?v=.... Utilizza invece lo strumento YouTube l'API iframe Player, che è il modo ufficiale per riprodurre i video di YouTube su Android.

Stuttering della riproduzione del video

Il dispositivo potrebbe non essere in grado di decodificare i contenuti abbastanza velocemente se, ad esempio, la velocità in bit o la risoluzione dei contenuti supera le capacità del dispositivo. Potresti aver bisogno di utilizzare contenuti di qualità inferiore per ottenere buone prestazioni su questi dispositivi.

Se il video si interrompe su un dispositivo con una versione di Android da Android 6.0 (livello API 23) fino ad Android 11 (livello API 30) incluso, in particolare quando riproduci contenuti protetti con DRM o con frequenza fotogrammi elevata, puoi abilitando l'accodamento asincrono del buffer.

Errori di lint dell'API instabile

Media3 garantisce la compatibilità binaria per un sottoinsieme della piattaforma API. La parti che non garantiscono la compatibilità binaria sono contrassegnate con @UnstableApi Per chiarire questa distinzione, gli utilizzi delle I simboli delle API generano un errore di lint a meno che non siano annotati con @OptIn.

L'annotazione @UnstableApi non implica nulla sulla qualità o sulle prestazioni di un'API, ma solo sul fatto che non è "bloccata dall'API".

Hai due opzioni per gestire gli errori di lint instabili dell'API:

  • Passa all'utilizzo di un'API stabile che ottiene lo stesso risultato.
  • Continua a utilizzare l'API instabile e annota l'utilizzo con @OptIn, come mostrati in seguito.
Aggiungi l'annotazione @OptIn

Android Studio può aiutarti ad aggiungere l'annotazione:

Screenshot: Come aggiungere l'annotazione di attivazione
Figura 2: aggiunta di un'annotazione @androidx.annotations.OptIn con Android Studio.

Puoi anche annotare manualmente siti di utilizzo specifici in Kotlin:

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }

E anche in Java:

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }

Puoi attivare interi pacchetti aggiungendo un file package-info.java:

@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

È possibile attivare interi progetti eliminando l'errore di lint specifico nei rispettivi lint.xml file:

 <?xml version="1.0" encoding="utf-8"?>
 <lint>
   <issue id="UnsafeOptInUsageError">
     <option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
   </issue>
 </lint>

Esiste anche un'annotazione kotlin.OptIn che non dovrebbe essere utilizzata. È è importante usare l'annotazione androidx.annotation.OptIn.