- Correggere gli errori "Cleartext HTTP traffic not permitted"
- Correggere gli errori "SSLHandshakeException", "CertPathValidatorException" e "ERR_CERT_AUTHORITY_INVALID"
- Perché alcuni file multimediali non sono ricercabili?
- Perché la ricerca è imprecisa in alcuni file MP3?
- Perché la ricerca nel mio video è lenta?
- Perché alcuni file MPEG-TS non vengono riprodotti?
- Perché i sottotitoli non vengono trovati in alcuni file MPEG-TS?
- Perché alcuni file MP4/FMP4 vengono riprodotti in modo errato?
- Perché alcuni stream non vengono riprodotti con il codice di risposta HTTP 301 o 302?
- Perché alcuni stream non vengono riprodotti con UnrecognizedInputFormatException?
- Perché setPlaybackParameters non funziona correttamente su alcuni dispositivi?
- Che cosa significano gli errori "Player is accessed on the wrong thread"?
- Come faccio a correggere l'errore "Unexpected status line: ICY 200 OK"?
- Come faccio a eseguire una query per verificare se lo stream in riproduzione è un live streaming?
- Come faccio a mantenere la riproduzione dell'audio quando la mia app è in background?
- Perché ExoPlayer supporta i miei contenuti, ma la libreria ExoPlayer Cast no?
- Perché i contenuti non vengono riprodotti, ma non viene visualizzato alcun errore?
- Come faccio a caricare una libreria di decodifica e a utilizzarla per la riproduzione?
- Posso riprodurre i video di YouTube direttamente con ExoPlayer?
- La riproduzione video è a scatti
- Errori di lint dell'API non stabile
Correggere gli errori "Cleartext HTTP traffic not permitted"
Questo errore si verifica se la tua app richiede traffico HTTP in testo normale (ovvero http:// anziché https://) quando la sua configurazione della sicurezza di rete non lo consente. Se la tua app ha come target Android 9 (livello API 28) o versioni successive, il traffico HTTP in testo normale è disattivato nella configurazione predefinita.
Se la tua app deve funzionare con il traffico HTTP in testo normale, devi utilizzare una configurazione della sicurezza di rete che lo consenta. Per maggiori dettagli, consulta la documentazione sulla sicurezza di rete di Android
. Per attivare tutto il traffico HTTP in testo normale, puoi semplicemente aggiungere
android:usesCleartextTraffic="true" all'elemento application di
AndroidManifest.xml della tua app.
L'app demo di ExoPlayer utilizza la configurazione della sicurezza di rete predefinita, pertanto non consente il traffico HTTP in testo normale. Puoi attivarlo seguendo le istruzioni riportate sopra.
Correggere gli errori "SSLHandshakeException", "CertPathValidatorException" e "ERR_CERT_AUTHORITY_INVALID"
SSLHandshakeException, CertPathValidatorException e ERR_CERT_AUTHORITY_INVALID indicano tutti un problema con il certificato SSL del server. Questi errori non sono specifici di ExoPlayer. Per maggiori dettagli, consulta la documentazione SSL di Android
.
Perché alcuni file multimediali non sono ricercabili?
Per impostazione predefinita, ExoPlayer non supporta la ricerca nei contenuti multimediali in cui l'unico metodo per eseguire operazioni di ricerca accurate è la scansione e l'indicizzazione dell'intero file da parte del player. ExoPlayer considera questi file non ricercabili. La maggior parte dei formati di container multimediali moderni include metadati per la ricerca (ad esempio un indice di esempio), ha un algoritmo di ricerca ben definito (ad esempio, la ricerca di bisezione interpolata per Ogg) o indica che i contenuti hanno una velocità in bit costante. In questi casi, le operazioni di ricerca efficienti sono possibili e supportate da ExoPlayer.
Se hai bisogno della ricerca, ma hai contenuti multimediali non ricercabili, ti consigliamo di convertire i contenuti in un formato di container più appropriato. Per i file MP3, ADTS e AMR, puoi anche attivare la ricerca presupponendo che i file abbiano una velocità in bit costante, come descritto qui.
Perché la ricerca è imprecisa in alcuni file MP3?
I file MP3 con velocità in bit variabile (VBR) non sono adatti ai casi d'uso che richiedono una ricerca esatta. Esistono due motivi:
- Per una ricerca esatta, un formato di container dovrebbe idealmente fornire una mappatura precisa da tempo a byte in un'intestazione. Questa mappatura consente a un player di mappare un tempo di ricerca richiesto all'offset di byte corrispondente e di iniziare a richiedere, analizzare e riprodurre i contenuti multimediali da quell'offset. Le intestazioni disponibili per specificare questa mappatura in MP3 (ad esempio le intestazioni XING) sono, purtroppo, spesso imprecise.
- Per i formati di container che non forniscono una mappatura precisa da tempo a byte (o nessuna mappatura da tempo a byte), è comunque possibile eseguire una ricerca esatta se il container include timestamp di esempio assoluti nello stream. In questo caso, un player può mappare il tempo di ricerca a una stima migliore dell'offset di byte corrispondente, iniziare a richiedere contenuti multimediali da quell'offset, analizzare il primo timestamp di esempio assoluto ed eseguire una ricerca binaria guidata nei contenuti multimediali finché non trova l'esempio corretto. Purtroppo, MP3 non include timestamp di esempio assoluti nello stream, quindi questo approccio non è possibile.
Per questi motivi, l'unico modo per eseguire una ricerca esatta in un file MP3 VBR è scansionare l'intero file e creare manualmente una mappatura da tempo a byte nel player. Questa strategia può essere attivata utilizzando FLAG_ENABLE_INDEX_SEEKING,
che può essere impostato su un DefaultExtractorsFactory utilizzando
setMp3ExtractorFlags. Tieni presente che non è scalabile per i file MP3 di grandi dimensioni, in particolare se l'utente tenta di eseguire la ricerca verso la fine dello stream poco dopo l'inizio della riproduzione, il che richiede al player di attendere il download e l'indicizzazione dell'intero stream prima di eseguire la ricerca. In ExoPlayer, abbiamo
deciso di ottimizzare la velocità rispetto all'accuratezza in questo caso e
FLAG_ENABLE_INDEX_SEEKING è quindi disabilitato per impostazione predefinita.
Se controlli i contenuti multimediali che stai riproducendo, ti consigliamo vivamente di utilizzare un formato di container più appropriato, ad esempio MP4. Non siamo a conoscenza di casi d'uso in cui MP3 sia la scelta migliore per il formato multimediale.
Perché la ricerca nel mio video è lenta?
Quando il player cerca una nuova posizione di riproduzione in un video, deve eseguire due operazioni:
- Caricare i dati corrispondenti alla nuova posizione di riproduzione nel buffer (potrebbe non essere necessario se questi dati sono già memorizzati nel buffer).
- Svuotare il decodificatore video e iniziare la decodifica dal frame I (fotogramma chiave) prima della nuova posizione di riproduzione, a causa della codifica intra-frame utilizzata dalla maggior parte dei formati di compressione video. Per garantire che la ricerca sia accurata (ovvero che la riproduzione inizi esattamente nella posizione di ricerca), tutti i frame tra il frame I precedente e la posizione di ricerca devono essere decodificati e scartati immediatamente (senza essere visualizzati sullo schermo).
La latenza introdotta da (1) può essere ridotta aumentando la quantità di dati memorizzati nel buffer in memoria dal player o pre-memorizzando nella cache i dati su disco.
La latenza introdotta da (2) può essere ridotta diminuendo l'accuratezza
della ricerca utilizzando ExoPlayer.setSeekParameters o ricodificando il video
in modo che abbia frame I più frequenti (il che comporterà 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 basa sugli AUD per rilevare a basso costo i limiti dei frame. Allo stesso modo, alcuni file MPEG-TS non contengono fotogrammi chiave IDR. Per impostazione predefinita, questi sono gli unici tipi di fotogrammi chiave considerati da ExoPlayer.
Quando viene chiesto di riprodurre un file MPEG-TS privo di AUD o fotogrammi chiave IDR, ExoPlayer sembra bloccato nello stato di buffering. 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 un
DefaultExtractorsFactory utilizzando setTsExtractorFlags o su un
DefaultHlsExtractorFactory utilizzando il
costruttore.
L'utilizzo di FLAG_DETECT_ACCESS_UNITS non ha effetti collaterali, a parte il fatto che è costoso dal punto di vista computazionale rispetto al rilevamento dei limiti dei frame basato su AUD. L'utilizzo di FLAG_ALLOW_NON_IDR_KEYFRAMES può causare un danneggiamento visivo temporaneo all'inizio della riproduzione e immediatamente dopo le ricerche durante la riproduzione di alcuni file MPEG-TS.
Perché i sottotitoli non vengono trovati in alcuni file MPEG-TS?
Alcuni file MPEG-TS includono tracce CEA-608, ma non le dichiarano nei metadati del container, quindi ExoPlayer non è in grado di rilevarle. Puoi specificare manualmente le tracce dei sottotitoli fornendo un elenco dei formati di sottotitoli previsti a DefaultExtractorsFactory, inclusi i canali di accessibilità 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 vengono riprodotti in modo errato?
Alcuni file MP4/FMP4 contengono elenchi di modifiche che riscrivono la sequenza temporale dei contenuti multimediali saltando, spostando o ripetendo gli elenchi di esempi. ExoPlayer supporta parzialmente l'applicazione degli elenchi di modifiche. Ad esempio, può ritardare o ripetere gruppi di esempi a partire da un esempio di sincronizzazione, ma non tronca gli esempi audio o i contenuti multimediali di preroll per le modifiche che non iniziano con un esempio di sincronizzazione.
Se noti che una parte dei contenuti multimediali manca o viene ripetuta in modo imprevisto,
prova a impostare Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS o
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, in modo che
l'estrattore ignori completamente gli elenchi di modifiche. Questi possono essere impostati su un
DefaultExtractorsFactory utilizzando setMp4ExtractorFlags o
setFragmentedMp4ExtractorFlags.
Perché alcuni stream non vengono riprodotti con il codice di risposta HTTP 301 o 302?
I codici di risposta HTTP 301 e 302 indicano entrambi il reindirizzamento. Brevi descrizioni sono disponibili su Wikipedia. Quando ExoPlayer effettua una richiesta e riceve una risposta con il codice di stato 301 o 302, in genere segue il reindirizzamento e avvia la riproduzione normalmente. L'unico caso in cui questo non accade per impostazione predefinita è per i reindirizzamenti tra protocolli. Un reindirizzamento tra protocolli è quello che reindirizza da HTTPS a HTTP o viceversa (o, meno comunemente, tra un'altra coppia di protocolli). Puoi verificare se un URL causa un reindirizzamento tra protocolli utilizzando lo strumento da riga di comando wget come segue:
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
L'output dovrebbe essere simile al seguente:
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
In questo esempio sono presenti due reindirizzamenti. Il primo reindirizzamento va da https://yourserver.example.com/test.mp3 a https://secondserver.example.net/test.mp3. Entrambi sono HTTPS, quindi non si tratta di un reindirizzamento tra protocolli. Il secondo reindirizzamento va da https://secondserver.example.net/test.mp3 a http://thirdserver.example.org/test.mp3. Questo reindirizza da HTTPS a HTTP e quindi è un reindirizzamento tra protocolli. ExoPlayer non seguirà questo reindirizzamento nella sua configurazione predefinita, il che significa che la riproduzione non riuscirà.
Se necessario, puoi configurare ExoPlayer in modo che segua i reindirizzamenti tra protocolli
quando crei istanze di DefaultHttpDataSource.Factory utilizzate nella tua
applicazione. Scopri di più sulla selezione e la configurazione dello stack di rete
qui.
Perché alcuni stream non vengono riprodotti con UnrecognizedInputFormatException?
Questa domanda riguarda gli errori di riproduzione del seguente modulo:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
Esistono due possibili cause di questo errore. La causa più comune è che stai tentando di riprodurre contenuti DASH (mpd), HLS (m3u8) o SmoothStreaming (ism, isml), ma il player tenta di riprodurli come uno stream progressivo. Per riprodurre questi
stream, devi dipendere dal rispettivo modulo ExoPlayer. Nei casi in cui l'URI dello stream non termina con l'estensione del file standard, puoi anche passare MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 o MimeTypes.APPLICATION_SS a setMimeType di MediaItem.Builder per specificare esplicitamente il tipo di stream.
La seconda causa, meno comune, è che ExoPlayer non supporta il formato di container dei contenuti multimediali che stai tentando di riprodurre. In questo caso, l'errore funziona come previsto, ma non esitare a inviare una richiesta di funzionalità al nostro Issue Tracker, includendo i dettagli del formato del container e uno stream di test. 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, potresti
riscontrare prestazioni a scatti, artefatti audio e un elevato utilizzo della CPU quando
utilizzi l'API setPlaybackParameters. Questo perché un'ottimizzazione importante per questa API è disattivata per le build di debug in esecuzione su queste versioni di Android.
È importante notare che questo problema riguarda solo le build di debug. Non riguarda le build di release, per le quali l'ottimizzazione è sempre attiva. Di conseguenza, le release che fornisci agli utenti finali non dovrebbero essere interessate da questo problema.
Che cosa significano gli errori "Player is accessed on the wrong thread"?
Consulta Una nota sui thread nella pagina Guida introduttiva.
Come faccio a correggere l'errore "Unexpected status line: ICY 200 OK"?
Questo problema può verificarsi se la risposta del server include una riga di stato ICY anziché una conforme a HTTP. Le righe di stato ICY sono obsolete e non devono essere utilizzate, quindi se controlli il server devi aggiornarlo in modo che fornisca una risposta conforme a HTTP. Se non riesci a farlo, l'utilizzo della libreria ExoPlayer OkHttp risolverà il problema, poiché è in grado di gestire correttamente le righe di stato ICY.
Come faccio a eseguire una query per verificare 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 se continua ad aggiornarsi nel tempo).
Come faccio a mantenere la riproduzione dell'audio quando la mia app è in background?
Segui questi passaggi per garantire la riproduzione continua dell'audio quando la tua app è in background:
- Devi avere un servizio in primo piano in esecuzione. In questo modo il sistema non interrompe il processo per liberare risorse.
- Devi mantenere un
WifiLocke unWakeLock. In questo modo il sistema mantiene attivi la radio Wi-Fi e la CPU. Se utilizziExoPlayer, puoi farlo facilmente chiamandosetWakeMode, che acquisirà e rilascerà automaticamente i blocchi richiesti al momento giusto.
È importante rilasciare i blocchi (se non utilizzi setWakeMode) e interrompere il servizio non appena l'audio non viene più riprodotto.
Perché ExoPlayer supporta i miei contenuti, ma la libreria ExoPlayer Cast no?
È possibile che i contenuti che stai tentando di riprodurre non siano abilitati per CORS. Il framework Cast richiede che i contenuti siano abilitati per CORS per poter essere riprodotti.
Perché i contenuti non vengono riprodotti, ma non viene visualizzato alcun errore?
È possibile che il dispositivo su cui stai riproducendo i contenuti non supporti un formato di esempio multimediale specifico. Puoi verificarlo facilmente aggiungendo
un EventLogger come listener al player e cercando una riga
simile a questa 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 il formato di esempio multimediale specificato da mimeType. Per informazioni sui formati di esempio supportati, consulta la documentazione sui formati multimediali di Android. Potrebbe essere utile anche
Come faccio a caricare una libreria di decodifica e a utilizzarla per la riproduzione?
Come faccio a caricare una libreria di decodifica e a utilizzarla per la riproduzione?
- La maggior parte delle librerie di decodifica prevede passaggi manuali per estrarre e creare le dipendenze, quindi assicurati di aver seguito i passaggi descritti nel file README della libreria pertinente. Ad esempio, per la libreria ExoPlayer FFmpeg è necessario seguire le istruzioni riportate in libraries/decoder_ffmpeg/README.md, inclusa l'impostazione dei flag di configurazione per attivare i decodificatori per tutti i formati che vuoi riprodurre.
- Per le librerie con codice nativo, assicurati di utilizzare la versione corretta di Android NDK come specificato nel file README e cerca eventuali errori visualizzati durante la configurazione e la creazione. Dopo aver seguito i passaggi descritti nel file README, dovresti visualizzare i file
.sonella sottodirectorylibsdel percorso della libreria per ogni architettura supportata. - Per provare la riproduzione utilizzando la libreria nell'applicazione demo, consulta la sezione relativa all' attivazione dei decodificatori in bundle. Per istruzioni sull'utilizzo della libreria dalla tua app, consulta il file README della libreria.
- Se utilizzi
DefaultRenderersFactory, dovresti visualizzare una riga di log a livello di informazioni come "Loaded FfmpegAudioRenderer" in Logcat quando il decodificatore viene caricato. Se non la vedi, assicurati che l'applicazione abbia una dipendenza dalla libreria di decodifica. - Se in Logcat vedi log a livello di avviso da
LibraryLoader, questo significa che il caricamento del componente nativo della libreria non è riuscito. In questo caso, verifica di aver seguito correttamente i passaggi descritti nel file README della libreria e che non siano stati generati errori durante l'esecuzione delle istruzioni.
Se continui a riscontrare problemi con l'utilizzo delle librerie di decodifica, controlla l' Issue Tracker di Media3 per eventuali problemi recenti pertinenti. Se devi segnalare un nuovo problema relativo alla creazione della parte nativa della libreria, includi l'output completo della riga di comando dell'esecuzione delle istruzioni del file README per aiutarci a diagnosticare il problema.
Posso riprodurre i video di YouTube direttamente con ExoPlayer?
No, ExoPlayer non può riprodurre video di YouTube, ad esempio URL del modulo https://www.youtube.com/watch?v=.... Ti consigliamo invece di utilizzare l'API YouTube
iFrame Player,
che è il modo ufficiale per riprodurre i video di YouTube su Android.
La riproduzione video è a scatti
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 superano le capacità del dispositivo. Potresti dover utilizzare contenuti di qualità inferiore per ottenere buone prestazioni su questi dispositivi.
Se riscontri problemi di riproduzione video a scatti 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 durante la riproduzione di contenuti protetti da DRM o con frame rate elevato, puoi provare ad attivare l'accodamento asincrono dei buffer.
Errori di lint dell'API non stabile
Media3 garantisce la compatibilità binaria per un sottoinsieme della superficie dell'API. Le
parti che non garantiscono la compatibilità binaria sono contrassegnate con
@UnstableApi. Per rendere chiara questa distinzione, gli utilizzi dei simboli dell'API non stabile generano un errore di lint a meno che non siano annotati con @OptIn.
L'annotazione @UnstableApi non implica nulla in merito alla qualità o al rendimento di un'API, ma solo il fatto che non è "API-frozen".
Hai due opzioni per gestire gli errori di lint dell'API non stabile:
- Passa all'utilizzo di un'API stabile che ottiene lo stesso risultato.
- Continua a utilizzare l'API non stabile e annota l'utilizzo con
@OptIn, come mostrato di seguito.
Aggiungere l'annotazione @OptIn
Android Studio può aiutarti ad aggiungere l'annotazione:
Puoi anche annotare manualmente siti di utilizzo specifici:
Kotlin
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
Java
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
È possibile attivare interi pacchetti aggiungendo un file package-info:
Kotlin
// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
Java
// In your 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 sopprimendo l'errore di lint specifico nel loro
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 deve essere utilizzata. È importante utilizzare l'annotazione androidx.annotation.OptIn.