- Résoudre les erreurs "Trafic HTTP en texte clair non autorisé"
- Résoudre les erreurs "SSLHandshakeException", "CertPathValidatorException" et "ERR_CERT_AUTHORITY_INVALID"
- Pourquoi certains fichiers multimédias ne sont-ils pas consultables ?
- Pourquoi la consultation est-elle imprécise dans certains fichiers MP3 ?
- Pourquoi la consultation est-elle lente dans ma vidéo ?
- Pourquoi certains fichiers MPEG-TS ne sont-ils pas lus ?
- Pourquoi les sous-titres ne sont-ils pas trouvés dans certains fichiers MPEG-TS ?
- Pourquoi certains fichiers MP4/FMP4 ne sont-ils pas lus correctement ?
- Pourquoi certains flux échouent-ils avec le code de réponse HTTP 301 ou 302 ?
- Pourquoi certains flux échouent-ils avec UnrecognizedInputFormatException ?
- Pourquoi setPlaybackParameters ne fonctionne-t-il pas correctement sur certains appareils ?
- Que signifient les erreurs "Le lecteur est accessible sur le mauvais thread" ?
- Comment résoudre le problème "Ligne d'état inattendue : ICY 200 OK" ?
- Comment savoir si le flux en cours de lecture est un flux en direct ?
- Comment continuer à lire l'audio lorsque mon application est en arrière-plan ?
- Pourquoi ExoPlayer est-il compatible avec mon contenu, mais pas la bibliothèque ExoPlayer Cast ?
- Pourquoi le contenu ne peut-il pas être lu, mais aucune erreur n'est signalée ?
- Comment charger une bibliothèque de décodage et l'utiliser pour la lecture ?
- Puis-je lire des vidéos YouTube directement avec ExoPlayer ?
- La lecture vidéo est saccadée
- Erreurs Lint d'API instable
Résoudre les erreurs "Trafic HTTP en texte clair non autorisé"
Cette erreur se produit si votre application demande un trafic HTTP en texte clair (c'est-à-dire http:// au lieu de https://) lorsque sa configuration de sécurité réseau ne l'autorise pas. Si votre application cible Android 9 (niveau d'API 28) ou une version ultérieure, le trafic HTTP en texte clair est désactivé par la configuration par défaut.
Si votre application doit fonctionner avec un trafic HTTP en texte clair, vous devez utiliser une configuration de sécurité réseau qui l'autorise. Pour en savoir plus, consultez la documentation sur la sécurité réseau d'Android
. Pour activer tout le trafic HTTP en texte clair, il vous suffit d'ajouter
android:usesCleartextTraffic="true" à l'élément application du fichier
AndroidManifest.xml de votre application.
L'application de démonstration ExoPlayer utilise la configuration de sécurité réseau par défaut et n'autorise donc pas le trafic HTTP en texte clair. Vous pouvez l'activer en suivant les instructions ci-dessus.
Résoudre les erreurs "SSLHandshakeException", "CertPathValidatorException" et "ERR_CERT_AUTHORITY_INVALID"
SSLHandshakeException, CertPathValidatorException et ERR_CERT_AUTHORITY_INVALID indiquent toutes un problème avec le certificat SSL du serveur. Ces erreurs ne sont pas spécifiques à ExoPlayer. Pour en savoir plus, consultez la documentation SSL d'Android
.
Pourquoi certains fichiers multimédias ne sont-ils pas consultables ?
Par défaut, ExoPlayer n'est pas compatible avec la consultation dans les contenus multimédias où la seule méthode permettant d'effectuer des opérations de consultation précises consiste à ce que le lecteur analyse et indexe l'intégralité du fichier. ExoPlayer considère ces fichiers comme non consultables. La plupart des formats de conteneurs multimédias modernes incluent des métadonnées pour la consultation (telles qu'un index d'échantillons), disposent d'un algorithme de consultation bien défini (par exemple, une recherche par bissection interpolée pour Ogg) ou indiquent que leur contenu est à débit constant. Dans ces cas, des opérations de consultation efficaces sont possibles et prises en charge par ExoPlayer.
Si vous avez besoin de consulter des contenus multimédias non consultables, nous vous suggérons de les convertir pour utiliser un format de conteneur plus approprié. Pour les fichiers MP3, ADTS et AMR, vous pouvez également activer la consultation en supposant que les fichiers ont un débit constant, comme décrit ici.
Pourquoi la consultation est-elle imprécise dans certains fichiers MP3 ?
Les fichiers MP3 à débit variable (VBR) ne conviennent fondamentalement pas aux cas d'utilisation qui nécessitent une consultation exacte. Il y a deux raisons à cela :
- Pour une consultation exacte, un format de conteneur fournit idéalement un mappage précis entre le temps et les octets dans un en-tête. Ce mappage permet à un lecteur de mapper un temps de consultation demandé à l'offset d'octet correspondant, et de commencer à demander, à analyser et à lire le contenu multimédia à partir de cet offset. Malheureusement, les en-têtes disponibles pour spécifier ce mappage au format MP3 (tels que les en-têtes XING) sont souvent imprécis.
- Pour les formats de conteneurs qui ne fournissent pas de mappage précis entre le temps et les octets (ou aucun mappage entre le temps et les octets), il est toujours possible d'effectuer une consultation exacte si le conteneur inclut des codes temporels d'échantillons absolus dans le flux. Dans ce cas, un lecteur peut mapper le temps de consultation à une meilleure estimation de l'offset d'octet correspondant, commencer à demander le contenu multimédia à partir de cet offset, analyser le premier code temporel d'échantillon absolu et effectuer une recherche binaire guidée dans le contenu multimédia jusqu'à ce qu'il trouve l'échantillon approprié. Malheureusement, le format MP3 n'inclut pas de codes temporels d'échantillons absolus dans le flux. Cette approche n'est donc pas possible.
Pour ces raisons, la seule façon d'effectuer une consultation exacte dans un fichier MP3 VBR consiste à analyser l'intégralité du fichier et à créer manuellement un mappage entre le temps et les octets dans le lecteur. Cette stratégie peut être activée à l'aide de FLAG_ENABLE_INDEX_SEEKING,
qui peut être défini sur un DefaultExtractorsFactory à l'aide de
setMp3ExtractorFlags. Notez qu'elle ne s'adapte pas bien aux fichiers MP3 volumineux, en particulier si l'utilisateur tente de consulter la fin du flux peu de temps après le début de la lecture. Le lecteur doit alors attendre d'avoir téléchargé et indexé l'intégralité du flux avant d'effectuer la consultation. Dans ExoPlayer, nous
avons décidé d'optimiser la vitesse plutôt que la précision dans ce cas et
FLAG_ENABLE_INDEX_SEEKING est donc désactivé par défaut.
Si vous contrôlez le contenu multimédia que vous lisez, nous vous conseillons vivement d'utiliser un format de conteneur plus approprié, tel que MP4. Nous ne connaissons aucun cas d'utilisation où le format MP3 est le meilleur choix.
Pourquoi la consultation est-elle lente dans ma vidéo ?
Lorsque le lecteur recherche une nouvelle position de lecture dans une vidéo, il doit effectuer deux opérations :
- Charger les données correspondant à la nouvelle position de lecture dans le tampon (cela n'est peut-être pas nécessaire si ces données sont déjà mises en mémoire tampon).
- Vider le décodeur vidéo et commencer le décodage à partir de l'image I (image clé) avant la nouvelle position de lecture, en raison du codage intra-image utilisé par la plupart des formats de compression vidéo. Pour s'assurer que la consultation est précise (c'est-à-dire que la lecture commence exactement à la position de consultation), toutes les images entre l'image I précédente et la position de consultation doivent être décodées et immédiatement supprimées (sans être affichées à l'écran).
La latence introduite par (1) peut être réduite en augmentant la quantité de données mises en mémoire tampon par le lecteur ou en mise en cache préalable des données sur le disque.
La latence introduite par (2) peut être atténuée en réduisant la précision de la consultation à l'aide de ExoPlayer.setSeekParameters ou en réencodant la vidéo pour qu'elle contienne des images I plus fréquentes (ce qui entraînera un fichier de sortie plus volumineux).
Pourquoi certains fichiers MPEG-TS ne sont-ils pas lus ?
Certains fichiers MPEG-TS ne contiennent pas de délimiteurs d'unité d'accès (AUD). Par défaut, ExoPlayer s'appuie sur les AUD pour détecter facilement les limites des images. De même, certains fichiers MPEG-TS ne contiennent pas d'images clés IDR. Par défaut, il s'agit du seul type d'images clés pris en compte par ExoPlayer.
ExoPlayer semble bloqué dans l'état de mise en mémoire tampon lorsqu'il est invité à lire un fichier MPEG-TS qui ne contient pas d'AUD ni d'images clés IDR. Si vous devez lire de tels fichiers,
vous pouvez le faire en utilisant FLAG_DETECT_ACCESS_UNITS et
FLAG_ALLOW_NON_IDR_KEYFRAMES respectivement. Ces indicateurs peuvent être définis sur un
DefaultExtractorsFactory à l'aide de setTsExtractorFlags ou sur un
DefaultHlsExtractorFactory à l'aide du
constructeur.
L'utilisation de FLAG_DETECT_ACCESS_UNITS n'a aucun effet secondaire autre que le fait d'être coûteuse en calcul par rapport à la détection des limites d'images basée sur les AUD. L'utilisation de FLAG_ALLOW_NON_IDR_KEYFRAMES peut entraîner une corruption visuelle temporaire au début de la lecture et immédiatement après les consultations lors de la lecture de certains fichiers MPEG-TS.
Pourquoi les sous-titres ne sont-ils pas trouvés dans certains fichiers MPEG-TS ?
Certains fichiers MPEG-TS incluent des pistes CEA-608, mais ne les déclarent pas dans les métadonnées du conteneur. ExoPlayer n'est donc pas en mesure de les détecter. Vous pouvez spécifier manuellement toutes les pistes de sous-titres en fournissant une liste des formats de sous-titres attendus au DefaultExtractorsFactory, y compris les canaux d'accessibilité qui peuvent être utilisés pour les identifier dans le flux 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();
Pourquoi certains fichiers MP4/FMP4 ne sont-ils pas lus correctement ?
Certains fichiers MP4/FMP4 contiennent des listes de modifications qui réécrivent la chronologie des contenus multimédias en ignorant, en déplaçant ou en répétant des listes d'échantillons. ExoPlayer prend partiellement en charge l'application de listes de modifications. Par exemple, il peut retarder ou répéter des groupes d'échantillons en commençant par un échantillon de synchronisation, mais il ne tronque pas les échantillons audio ni les contenus multimédias pré-roll pour les modifications qui ne commencent pas par un échantillon de synchronisation.
Si une partie du contenu multimédia est manquante ou répétée de manière inattendue,
essayez de définir Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS ou
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS, ce qui entraînera
l'ignorance totale des listes de modifications par l'extracteur. Ces éléments peuvent être définis sur un
DefaultExtractorsFactory à l'aide de setMp4ExtractorFlags ou
setFragmentedMp4ExtractorFlags.
Pourquoi certains flux échouent-ils avec le code de réponse HTTP 301 ou 302 ?
Les codes de réponse HTTP 301 et 302 indiquent tous deux une redirection. Vous trouverez de brèves descriptions sur Wikipédia. Lorsque ExoPlayer effectue une requête et reçoit une réponse avec le code d'état 301 ou 302, il suit normalement la redirection et lance la lecture normalement. Le seul cas où cela ne se produit pas par défaut concerne les redirections inter-protocoles. Une redirection inter-protocole est une redirection d'HTTPS vers HTTP ou inversement (ou, moins fréquemment, entre une autre paire de protocoles). Vous pouvez tester si une URL provoque une redirection inter-protocole à l'aide de l'outil de ligne de commande wget comme suit :
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
Le résultat devrait ressembler à ceci :
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
Dans cet exemple, il existe deux redirections. La première redirection va de https://yourserver.example.com/test.mp3 à https://secondserver.example.net/test.mp3. Les deux sont HTTPS. Il ne s'agit donc pas d'une redirection inter-protocole. La deuxième redirection va de https://secondserver.example.net/test.mp3 à http://thirdserver.example.org/test.mp3. Cette redirection va d'HTTPS à HTTP. Il s'agit donc d'une redirection inter-protocole. ExoPlayer ne suivra pas cette redirection dans sa configuration par défaut, ce qui signifie que la lecture échouera.
Si nécessaire, vous pouvez configurer ExoPlayer pour qu'il suive les redirections inter-protocoles
lors de l'instanciation des instances DefaultHttpDataSource.Factory utilisées dans votre
application. Découvrez comment sélectionner et configurer la pile réseau
ici.
Pourquoi certains flux échouent-ils avec UnrecognizedInputFormatException ?
Cette question concerne les échecs de lecture du formulaire suivant :
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
Cet échec peut avoir deux causes. La cause la plus fréquente est que vous essayez de lire du contenu DASH (mpd), HLS (m3u8) ou SmoothStreaming (ism, isml), mais que le lecteur tente de le lire comme un flux progressif. Pour lire ces
flux, vous devez dépendre du module ExoPlayer correspondant. Dans les cas où l'URI du flux ne se termine pas par l'extension de fichier standard, vous pouvez également transmettre MimeTypes.APPLICATION_MPD, MimeTypes.APPLICATION_M3U8 ou MimeTypes.APPLICATION_SS à setMimeType de MediaItem.Builder pour spécifier explicitement le type de flux.
La deuxième cause, moins fréquente, est qu'ExoPlayer n'est pas compatible avec le format de conteneur du contenu multimédia que vous essayez de lire. Dans ce cas, l'échec fonctionne comme prévu. Toutefois, n'hésitez pas à envoyer une demande de fonctionnalité à notre outil de suivi des problèmes, en incluant des détails sur le format de conteneur et un flux de test. Veuillez rechercher une demande de fonctionnalité existante avant d'en envoyer une nouvelle.
Pourquoi setPlaybackParameters ne fonctionne-t-il pas correctement sur certains appareils ?
Lorsque vous exécutez une version de débogage de votre application sur Android M ou une version antérieure, vous pouvez
rencontrer des performances saccadées, des artefacts audibles et une utilisation élevée du processeur lorsque vous
utilisez l'API setPlaybackParameters. En effet, une optimisation importante pour cette API est désactivée pour les versions de débogage exécutées sur ces versions d'Android.
Il est important de noter que ce problème n'affecte que les versions de débogage. Il n'affecte pas les versions finales, pour lesquelles l'optimisation est toujours activée. Par conséquent, les versions que vous fournissez aux utilisateurs finaux ne devraient pas être affectées par ce problème.
Que signifient les erreurs "Le lecteur est accessible sur le mauvais thread" ?
Consultez la note sur le threading sur la page de démarrage.
Comment résoudre le problème "Ligne d'état inattendue : ICY 200 OK" ?
Ce problème peut se produire si la réponse du serveur inclut une ligne d'état ICY, plutôt qu'une ligne conforme à HTTP. Les lignes d'état ICY sont obsolètes et ne doivent pas être utilisées. Par conséquent, si vous contrôlez le serveur, vous devez le mettre à jour pour qu'il fournisse une réponse conforme à HTTP. Si vous ne pouvez pas le faire, l'utilisation de la bibliothèque ExoPlayer OkHttp résoudra le problème, car elle est en mesure de gérer correctement les lignes d'état ICY.
Comment savoir si le flux en cours de lecture est un flux en direct ?
Vous pouvez interroger la méthode isCurrentWindowLive du lecteur. De plus, vous
pouvez cocher isCurrentWindowDynamic pour savoir si la fenêtre est dynamique
(c'est-à-dire qu'elle est toujours mise à jour au fil du temps).
Comment continuer à lire l'audio lorsque mon application est en arrière-plan ?
Pour vous assurer que la lecture audio continue lorsque votre application est en arrière-plan, procédez comme suit :
- Vous devez disposer d'un service de premier plan en cours d'exécution. Cela empêche le système de supprimer votre processus pour libérer des ressources.
- Vous devez détenir un
WifiLocket unWakeLock. Cela garantit que le système maintient la radio Wi-Fi et le processeur actifs. Cela peut être fait facilement si vous utilisezExoPlayeren appelantsetWakeMode, qui acquerra et libérera automatiquement les verrous requis aux moments appropriés.
Il est important de libérer les verrous (si vous n'utilisez pas setWakeMode) et d'arrêter le service dès que l'audio n'est plus lu.
Pourquoi ExoPlayer est-il compatible avec mon contenu, mais pas la bibliothèque ExoPlayer Cast ?
Il est possible que le contenu que vous essayez de lire ne soit pas compatible avec CORS. Le framework Cast nécessite que le contenu soit compatible avec CORS pour pouvoir le lire.
Pourquoi le contenu ne peut-il pas être lu, mais aucune erreur n'est signalée ?
Il est possible que l'appareil sur lequel vous lisez le contenu ne soit pas compatible avec un format d'échantillon multimédia spécifique. Vous pouvez facilement le confirmer en ajoutant
un EventLogger en tant qu'écouteur à votre lecteur et en recherchant une ligne
semblable à celle-ci dans Logcat :
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE signifie que l'appareil n'est pas en mesure de décoder le format d'échantillon multimédia spécifié par mimeType. Pour en savoir plus sur les formats d'échantillons compatibles, consultez la documentation
sur les formats multimédias Android. La section Comment charger une bibliothèque de décodage et l'utiliser pour la lecture ? peut également être utile.
Comment charger une bibliothèque de décodage et l'utiliser pour la lecture ?
- La plupart des bibliothèques de décodeurs comportent des étapes manuelles pour extraire et créer les dépendances. Assurez-vous donc d'avoir suivi les étapes décrites dans le fichier README de la bibliothèque concernée. Par exemple, pour la bibliothèque ExoPlayer FFmpeg, il est nécessaire de suivre les instructions de libraries/decoder_ffmpeg/README.md, y compris de transmettre des indicateurs de configuration pour activer les décodeurs pour tous les formats que vous souhaitez lire.
- Pour les bibliothèques contenant du code natif, assurez-vous d'utiliser la version correcte du NDK Android, comme spécifié dans le fichier README, et recherchez les erreurs qui s'affichent lors de la configuration et de la compilation. Vous devriez voir des fichiers
.soapparaître dans le sous-répertoirelibsdu chemin d'accès de la bibliothèque pour chaque architecture compatible après avoir suivi les étapes décrites dans le fichier README. - Pour essayer la lecture à l'aide de la bibliothèque dans l'application de démonstration, consultez la section Activer les décodeurs groupés. Consultez le fichier README de la bibliothèque pour obtenir des instructions sur l'utilisation de la bibliothèque à partir de votre propre application.
- Si vous utilisez
DefaultRenderersFactory, vous devriez voir une ligne de journalisation de niveau info telle que "Loaded FfmpegAudioRenderer" dans Logcat lorsque le décodeur se charge. Si elle est manquante, assurez-vous que l'application dépend de la bibliothèque de décodage. - Si vous voyez des journaux de niveau avertissement de
LibraryLoaderdans Logcat, cela indique que le chargement du composant natif de la bibliothèque a échoué. Dans ce cas, vérifiez que vous avez suivi correctement les étapes décrites dans le fichier README de la bibliothèque et qu'aucune erreur n'a été générée lors du suivi des instructions.
Si vous rencontrez toujours des problèmes lors de l'utilisation des bibliothèques de décodage, veuillez consulter l'outil de suivi des problèmes Media3 pour connaître les problèmes récents pertinents. Si vous devez signaler un nouveau problème et qu'il concerne la compilation de la partie native de la bibliothèque, veuillez inclure la sortie complète de la ligne de commande lors de l'exécution des instructions du fichier README pour nous aider à diagnostiquer le problème.
Puis-je lire des vidéos YouTube directement avec ExoPlayer ?
Non, ExoPlayer ne peut pas lire de vidéos YouTube, telles que les URL au format https://www.youtube.com/watch?v=.... Vous devez plutôt utiliser l'API YouTube
iFrame Player,
qui est le moyen officiel de lire des vidéos YouTube sur Android.
La lecture vidéo est saccadée
L'appareil peut ne pas être en mesure de décoder le contenu assez rapidement si, par exemple, le débit ou la résolution du contenu dépassent les capacités de l'appareil. Vous devrez peut-être utiliser un contenu de qualité inférieure pour obtenir de bonnes performances sur ces appareils.
Si vous rencontrez des saccades vidéo sur un appareil exécutant une version d'Android allant d'Android 6.0 (niveau d'API 23) à Android 11 (niveau d'API 30) inclus, en particulier lors de la lecture de contenus protégés par DRM ou à fréquence d'images élevée, vous pouvez essayer d'activer la mise en file d'attente asynchrone des tampons.
Erreurs Lint d'API instable
Media3 garantit la compatibilité binaire pour un sous-ensemble de la surface de l'API. Les
parties qui ne garantissent pas la compatibilité binaire sont marquées avec
@UnstableApi. Pour clarifier cette distinction, les utilisations de symboles d'API instables génèrent une erreur Lint, sauf si elles sont annotées avec @OptIn.
L'annotation @UnstableApi n'implique rien quant à la qualité ou aux performances d'une API, mais uniquement qu'elle n'est pas "gelée".
Vous avez deux possibilités pour gérer les erreurs Lint d'API instables :
- Passez à une API stable qui obtient le même résultat.
- Continuez à utiliser l'API instable et annotez l'utilisation avec
@OptIn, comme indiqué plus loin.
Ajouter l'annotation @OptIn
Android Studio peut vous aider à ajouter l'annotation :
Vous pouvez également annoter manuellement des sites d'utilisation spécifiques :
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() { ... }
Vous pouvez activer des packages entiers en ajoutant un fichier 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;
Vous pouvez activer des projets entiers en supprimant l'erreur Lint spécifique dans leur
lint.xml fichier :
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="UnsafeOptInUsageError">
<option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
</issue>
</lint>
Il existe également une annotation kotlin.OptIn qui ne doit pas être utilisée. Il est important d'utiliser l'annotation androidx.annotation.OptIn.