- Corriger les erreurs "Trafic HTTP en texte clair non autorisé"
- Corriger les erreurs "SSLHandshakeException", "CertPathValidatorException" et "ERR_CERT_AUTHORITY_INVALID"
- Pourquoi la recherche de certains fichiers multimédias n'est-elle pas possible ?
- Pourquoi la recherche est-elle imprécise dans certains fichiers MP3 ?
- Pourquoi la recherche dans ma vidéo est-elle lente ?
- Pourquoi la lecture de certains fichiers MPEG-TS échoue-t-elle ?
- Pourquoi certains fichiers MPEG-TS ne contiennent-ils pas de sous-titres ?
- 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 une exception UnrecognizedInputFormatException ?
- Pourquoi setPlaybackParameters ne fonctionne-t-il pas correctement sur certains appareils ?
- Que signifient les erreurs "Le lecteur est accédé 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 une diffusion en direct ?
- Comment puis-je continuer à lire du contenu audio lorsque mon application est exécutée en arrière-plan ?
- Pourquoi ExoPlayer est-il compatible avec mon contenu, mais pas la bibliothèque Cast d'ExoPlayer ?
- Pourquoi la lecture du contenu échoue-t-elle, mais aucune erreur ne s'affiche ?
- Comment puis-je obtenir une bibliothèque de décodage à charger et à utiliser pour la lecture ?
- Puis-je lire des vidéos YouTube directement avec ExoPlayer ?
- La lecture de la vidéo est saccadée
- Erreurs lint instables de l'API
Corriger les erreurs "Trafic HTTP en texte clair non autorisé"
Cette erreur se produit si votre application demande du trafic HTTP en texte clair (c'est-à-dire http://
plutôt que https://
) alors que sa configuration de sécurité réseau ne le permet 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 du trafic HTTP en texte clair, vous devez utiliser une configuration de sécurité réseau qui le permet. Pour en savoir plus, consultez la documentation sur la sécurité réseau d'Android. Pour activer tout le trafic HTTP en texte clair, vous pouvez simplement ajouter android:usesCleartextTraffic="true"
à l'élément application
du AndroidManifest.xml
de votre application.
L'application de démonstration ExoPlayer utilise la configuration de sécurité réseau par défaut. Elle n'autorise donc pas le trafic HTTP en texte clair. Vous pouvez l'activer en suivant les instructions ci-dessus.
Correction des erreurs "SSLHandshakeException", "CertPathValidatorException" et "ERR_CERT_AUTHORITY_INVALID"
SSLHandshakeException
, CertPathValidatorException
et ERR_CERT_AUTHORITY_INVALID
indiquent tous 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 la recherche de certains fichiers multimédias n'est-elle pas possible ?
Par défaut, ExoPlayer n'est pas compatible avec la recherche dans les contenus multimédias où la seule méthode pour effectuer des opérations de recherche précises consiste à faire analyser et indexer l'intégralité du fichier. ExoPlayer considère ces fichiers comme impossibles à rechercher. La plupart des formats de conteneurs multimédias modernes incluent des métadonnées pour la recherche (telles qu'un index d'exemples). Ils disposent d'un algorithme de recherche bien défini (par exemple, la recherche en bissection interpolée pour Ogg) ou indiquent que leur contenu est à débit constant. Dans ce cas, des opérations de recherche efficaces sont possibles et prises en charge par ExoPlayer.
Si vous avez besoin d'effectuer une recherche, mais que vous disposez d'éléments multimédias impossibles à rechercher, nous vous suggérons de convertir votre contenu afin d'utiliser un format de conteneur plus approprié. Pour les fichiers MP3, ADTS et AMR, vous pouvez également activer la recherche en supposant que les fichiers ont un débit constant, comme décrit ici.
Pourquoi la recherche est-elle inexacte dans certains fichiers MP3 ?
Les fichiers MP3 à débit variable (VBR) ne sont pas adaptés aux cas d'utilisation nécessitant une recherche exacte. Pour deux raisons:
- Pour une recherche exacte, un format de conteneur fournira idéalement un mappage temps/octet précis dans un en-tête. Cette mise en correspondance permet à un lecteur de mapper un temps de recherche demandé avec le décalage d'octets correspondant, puis de commencer à demander, à analyser et à lire un contenu multimédia à partir de ce décalage. Les en-têtes disponibles pour spécifier ce mappage dans MP3 (tels que les en-têtes XING) sont malheureusement souvent imprécis.
- Pour les formats de conteneur qui ne fournissent pas de mappage de temps/octet précis (ou qui n'offre aucun mappage de temps à octet), il est toujours possible d'effectuer une recherche exacte si le conteneur inclut des horodatages d'échantillons absolus dans le flux. Dans ce cas, le lecteur peut mapper le temps de recherche à la meilleure estimation du décalage d'octets correspondant, commencer à demander des contenus multimédias à partir de ce décalage, analyser le code temporel du premier échantillon absolu et effectuer une recherche binaire guidée dans le contenu multimédia jusqu'à ce qu'il trouve le bon échantillon. Malheureusement, le format MP3 n'inclut pas d'échantillons absolus d'horodatages dans le flux. Cette approche n'est donc pas possible.
Pour toutes ces raisons, la seule façon d'effectuer une recherche exacte dans un fichier MP3 VBR est d'analyser l'intégralité du fichier et de créer manuellement un mappage temps-octet 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'il n'est pas adapté aux fichiers MP3 volumineux, en particulier si l'utilisateur tente d'atteindre la fin du flux peu de temps après le début de la lecture, ce qui nécessite que le lecteur attende que le flux soit téléchargé et indexé dans son intégralité avant d'effectuer la recherche. Dans ExoPlayer, nous avons décidé d'optimiser la vitesse plutôt que la précision dans ce cas. FLAG_ENABLE_INDEX_SEEKING
est donc désactivé par défaut.
Si vous contrôlez le contenu multimédia que vous lisez, nous vous recommandons vivement d'utiliser un format de conteneur plus approprié, tel que MP4. Nous ne connaissons aucun cas d'utilisation où le MP3 constituait le meilleur format multimédia.
Pourquoi la recherche dans ma vidéo est-elle lente ?
Lorsque le lecteur recherche une nouvelle position dans une vidéo, il doit effectuer deux opérations:
- Chargez 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).
- Vide le décodeur vidéo et commencez le décodage à partir de l'I-frame (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 que la recherche soit précise (c'est-à-dire que la lecture commence exactement à la position de recherche), toutes les images entre le frame iFrame précédent et la position de recherche doivent être décodées et immédiatement supprimées (sans être affichées à l'écran).
La latence introduite par (1) peut être atténuée soit en augmentant la quantité de données mises en mémoire tampon par le lecteur, soit en mettant en cache les données à l'avance sur le disque.
La latence introduite par (2) peut être atténuée soit en réduisant la précision de la recherche à l'aide de ExoPlayer.setSeekParameters
, soit en réencodant la vidéo pour avoir des I-frames plus fréquents (ce qui se traduira par un fichier de sortie plus volumineux).
Pourquoi la lecture de certains fichiers MPEG-TS échoue-t-elle ?
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 les limites de trame à moindre coût. 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é à l'état de mise en mémoire tampon lorsqu'il est invité à lire un fichier MPEG-TS sans images AUD ou IDR. Si vous devez lire ces fichiers, vous pouvez utiliser respectivement FLAG_DETECT_ACCESS_UNITS
et FLAG_ALLOW_NON_IDR_KEYFRAMES
. 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 hormis le coût de calcul élevé par rapport à la détection de limites de trame basée sur l'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 une recherche lors de la lecture de certains fichiers MPEG-TS.
Pourquoi les sous-titres sont-ils introuvables 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 ne peut donc pas les détecter. Vous pouvez spécifier manuellement des 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 timeline multimédia en ignorant, en déplaçant ou en répétant des listes d'échantillons. ExoPlayer est partiellement compatible avec l'application de listes de modifications. Par exemple, elle peut retarder ou répéter des groupes d'échantillons à partir d'un échantillon de synchronisation, mais elle ne tronque pas les échantillons audio ni les contenus multimédias pré-roll pour les modifications qui ne démarrent pas sur un échantillon de synchronisation.
Si vous constatez qu'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
. L'extracteur ignorera alors complètement les listes de modifications. Elles peuvent être définies 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. Lorsqu'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 interprotocoles. Une redirection interprotocole est une redirection de HTTPS vers HTTP ou inversement (ou, plus rarement, entre une autre paire de protocoles). Pour vérifier si une URL provoque une redirection interprotocole à l'aide de l'outil de ligne de commande wget, procédez comme suit:
wget "https://yourserver.com/test.mp3" 2>&1 | grep Location
Le résultat doit se présenter comme suit:
Location: https://second.com/test.mp3 [following]
Location: http://third.com/test.mp3 [following]
Dans cet exemple, il y a deux redirections. La première redirection part de https://yourserver.com/test.mp3
vers https://second.com/test.mp3
. Les deux protocoles sont HTTPS. Il ne s'agit donc pas d'une redirection interprotocole. La deuxième redirection part de https://second.com/test.mp3
vers http://third.com/test.mp3
. Il s'agit d'une redirection de HTTPS vers HTTP, et donc d'une redirection interprotocole. 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 interprotocoles lors de l'instanciation d'instances DefaultHttpDataSource.Factory
utilisées dans votre application. Pour en savoir plus sur la sélection et la configuration de la pile réseau, cliquez ici.
Pourquoi certains flux échouent-ils avec une exception UnrecognizedInputFormatException ?
Cette question concerne les échecs de lecture sous la forme suivante:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
Deux causes sont possibles. La cause la plus courante est que vous essayez de lire du contenu DASH (mpd), HLS (m3u8) ou SmoothStreaming (ism, isml), mais que le lecteur tente de le lire en tant que flux progressif. Pour lire de tels flux, vous devez dépendre du module ExoPlayer correspondant. Si l'URI de 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 courante, 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, mais n'hésitez pas à envoyer une demande de fonctionnalité à notre Issue Tracker, qui inclut des détails sur le format du 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 lors de l'utilisation de 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 ne concerne que les versions de débogage. Cela n'affecte pas les builds, pour lesquels 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 accédé sur le mauvais thread" ?
Consultez Remarque sur les threads sur la page de démarrage.
Comment résoudre le problème "Ligne d'état inattendue: ICY 200 OK" ?
Ce problème peut survenir si la réponse du serveur inclut une ligne d'état ICY plutôt qu'une ligne compatible 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 fournir une réponse conforme au protocole HTTP. Si vous n'y parvenez pas, vous pouvez utiliser la bibliothèque OkHttp d'ExoPlayer pour résoudre le problème, car elle peut gérer correctement les lignes d'état ICY.
Comment savoir si le flux en cours de lecture est une diffusion en direct ?
Vous pouvez interroger la méthode isCurrentWindowLive
du lecteur. De plus, vous pouvez vérifier isCurrentWindowDynamic
pour savoir si la fenêtre est dynamique (c'est-à-dire toujours en cours d'actualisation au fil du temps).
Comment puis-je continuer à lire du contenu audio lorsque mon application est exécutée en arrière-plan ?
Pour assurer la continuité de la lecture audio lorsque votre application est exécutée 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 d'arrêter votre processus pour libérer des ressources.
- Vous devez contenir un
WifiLock
et unWakeLock
. Celles-ci garantissent que le système maintient la radio Wi-Fi et le processeur actifs. Vous pouvez le faire facilement si vous utilisezExoPlayer
en appelantsetWakeMode
, qui acquiert et libère automatiquement les verrous requis au bon moment.
Il est important de débloquer les verrous (si vous n'utilisez pas setWakeMode
) et d'arrêter le service dès que le contenu audio n'est plus diffusé.
Pourquoi ExoPlayer est-il compatible avec mon contenu, mais pas la bibliothèque Cast d'ExoPlayer ?
Il est possible que le contenu que vous essayez de lire ne soit pas compatible avec CORS. Le framework Cast nécessite que CORS soit activé pour que le contenu puisse être lu.
Pourquoi la lecture du contenu échoue-t-elle, mais aucune erreur ne s'affiche ?
Il est possible que l'appareil sur lequel vous lisez le contenu n'est pas compatible avec un format d'échantillon multimédia spécifique. Vous pouvez facilement le vérifier 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'exemple de contenu multimédia spécifié par mimeType
. Consultez la documentation relative aux formats multimédias Android pour en savoir plus sur les exemples de formats compatibles. Comment puis-je obtenir une bibliothèque de décodage à charger et à utiliser pour la lecture ? peut également être utile.
Comment puis-je obtenir une bibliothèque de décodage à charger et à utiliser pour la lecture ?
- La plupart des bibliothèques de décodeur proposent des étapes manuelles pour vérifier et créer les dépendances. Assurez-vous donc d'avoir suivi les étapes du 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 en transmettant des indicateurs de configuration afin d'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 bonne version du NDK Android, comme spécifié dans le fichier README, et recherchez les erreurs qui apparaissent lors de la configuration et de la compilation. Après avoir suivi les étapes du fichier README, les fichiers
.so
devraient apparaître dans le sous-répertoirelibs
du chemin d'accès de la bibliothèque pour chaque architecture compatible. - Pour tester la lecture à l'aide de la bibliothèque dans l'application de démonstration, consultez la section Activer des décodeurs groupés. Consultez le fichier README de la bibliothèque pour savoir comment l'utiliser à partir de votre propre application.
- Si vous utilisez
DefaultRenderersFactory
, une ligne de journal au niveau des informations doit s'afficher, comme "Loaded FfmpegAudioRenderer" dans Logcat lors du chargement du décodeur. Si ce n'est pas le cas, assurez-vous que l'application est dépendante de la bibliothèque de décodage. - Si vous voyez des journaux au niveau des avertissements de
LibraryLoader
dans Logcat, cela signifie que le chargement du composant natif de la bibliothèque a échoué. Si cela se produit, vérifiez que vous avez correctement suivi les étapes du fichier README de la bibliothèque et qu'aucune erreur n'a été générée lors des instructions.
Si vous rencontrez toujours des problèmes lors de l'utilisation des bibliothèques de décodage, consultez l'outil de suivi des problèmes Media3 pour trouver les éventuels problèmes récents. Si vous devez signaler un nouveau problème et qu'il concerne la création de la partie native de la bibliothèque, veuillez inclure le résultat de la ligne de commande complète de l'exécution des instructions 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 depuis YouTube, telles que les URL au format https://www.youtube.com/watch?v=...
. Utilisez plutôt l'API YouTube iFrame Player, qui est la méthode officielle pour lire des vidéos YouTube sur Android.
La lecture de la 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épasse les capacités de l'appareil. Vous devrez peut-être utiliser du contenu de qualité inférieure pour obtenir de bonnes performances sur ces appareils.
Si vous rencontrez des problèmes de stuttering 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 lorsque vous lisez du contenu protégé par DRM ou à fréquence d'images élevée, vous pouvez essayer d'activer la mise en file d'attente de la mémoire tampon asynchrone.
Erreurs lint de l'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 que cette distinction soit claire, les utilisations de symboles d'API instables génèrent une erreur lint, sauf s'ils sont annotés avec @OptIn
.
L'annotation @UnstableApi
n'indique rien sur la qualité ni sur les performances d'une API, mais uniquement sur le fait qu'elle n'est pas "gelée par l'API".
Vous avez deux options pour gérer les erreurs lint instables de l'API:
- Passez à l'utilisation d'une API stable qui produit le même résultat.
- Continuez à utiliser l'API instable et annotez-la avec
@OptIn
, comme indiqué ultérieurement.
Ajouter l'annotation @OptIn
Android Studio peut vous aider à ajouter l'annotation:
![Capture d'écran: comment ajouter l'annotation d'activation](https://developer.android.com/static/media/media3/exoplayer/images/unstable-api.png?authuser=5&hl=fr)
Vous pouvez également annoter manuellement des sites d'utilisation spécifiques en Kotlin:
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
De même en 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.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 fichier lint.xml
:
<?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
.