Le framework multimédia Android permet de lire divers types de contenus multimédias courants.
permettant d'intégrer facilement de l'audio, de la vidéo et des images dans vos applications. Vous pouvez lire du contenu audio ou
vidéo provenant de fichiers multimédias stockés dans les ressources de votre application (ressources brutes), à partir de fichiers autonomes
dans le système de fichiers ou à partir d'un flux de données arrivant via une connexion réseau, le tout à l'aide des API MediaPlayer
.
Ce document explique comment utiliser
MediaPlayer
pour écrire une lecture multimédia
application qui interagit avec l'utilisateur et le système afin d'obtenir de bonnes performances
une expérience utilisateur agréable. Vous pouvez également
d'utiliser ExoPlayer, une solution Open Source personnalisable
Bibliothèque compatible avec les fonctionnalités hautes performances non disponible dans MediaPlayer
Remarque:Vous ne pouvez lire les données audio que sur la sortie standard. appareil. Il s'agit actuellement du haut-parleur de l'appareil mobile ou d'un casque Bluetooth. Vous ne pouvez pas faire sonner fichiers dans l'audio de la conversation lors d'un appel.
Principes de base
Les classes suivantes sont utilisées pour lire des sons et des vidéos dans le framework Android:
MediaPlayer
- Cette classe est l'API principale permettant de lire des contenus audio et vidéo.
AudioManager
- Cette classe gère les sources et la sortie audio d'un appareil.
Déclarations du fichier manifeste
Avant de commencer le développement de votre application à l'aide de MediaPlayer, assurez-vous que votre fichier manifeste les déclarations appropriées pour permettre l'utilisation des fonctionnalités associées.
- Autorisation Internet : si vous utilisez MediaPlayer pour lire des contenus en streaming via le réseau.
votre application doit demander un accès au réseau.
<uses-permission android:name="android.permission.INTERNET" />
- Autorisation de wakelock, si votre application de lecteur doit garder l'écran.
de s'assombrir ou de mettre le processeur en veille, ou utilise le
MediaPlayer.setScreenOnWhilePlaying()
ouMediaPlayer.setWakeMode()
, vous devez demander cette autorisation.<uses-permission android:name="android.permission.WAKE_LOCK" />
Utilisation de MediaPlayer
L'un des composants les plus importants du cadre
média est la
MediaPlayer
. Un objet de cette classe peut extraire, décoder et lire des contenus audio et vidéo.
avec une configuration minimale. Il est compatible avec plusieurs sources multimédias différentes, par exemple:
- Ressources locales
- URI internes, tels que ceux que vous pouvez obtenir auprès d'un résolveur de contenu
- URL externes (flux)
Pour obtenir la liste des formats multimédias compatibles avec Android, consultez la page Supports compatibles Formats.
Voici un exemple :
d'un contenu audio disponible en tant que ressource brute locale (enregistrée dans le fichier
répertoire res/raw/
):
Kotlin
var mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1) mediaPlayer.start() // no need to call prepare(); create() does that for you
Java
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1); mediaPlayer.start(); // no need to call prepare(); create() does that for you
Dans ce cas, une couche « brute » est un fichier que le système n'a pas ou essayer d'analyser d'une manière particulière. Cependant, le contenu de cette ressource ne doit pas au format audio brut. Il doit s'agir d'un fichier multimédia correctement encodé et formaté tous les formats acceptés.
Voici comment effectuer la lecture à partir d'un URI disponible localement dans le système (obtenues par le biais d'un résolveur de contenu, par exemple):
Kotlin
val myUri: Uri = .... // initialize Uri here val mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(applicationContext, myUri) prepare() start() }
Java
Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();
Voici à quoi ressemble la lecture à partir d'une URL distante via un streaming HTTP:
Kotlin
val url = "http://........" // your URL here val mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(url) prepare() // might take long! (for buffering, etc) start() }
Java
String url = "http://........"; // your URL here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); // might take long! (for buffering, etc) mediaPlayer.start();
Remarque: Si vous transmettez une URL pour diffuser en streaming un fichier multimédia en ligne, le fichier doit pouvoir : téléchargement progressif.
Attention:Vous devez soit attraper, soit passer
IllegalArgumentException
et IOException
lors de l'utilisation
setDataSource()
, car
le fichier que vous référencez
n'existe peut-être pas.
Préparation asynchrone
L'utilisation de MediaPlayer
peut être simple dans
sur ce principe. Cependant, il est important de garder
à l’esprit que quelques autres éléments sont
pour l'intégrer correctement à une application Android classique. Pour
Par exemple, l'appel de prepare()
peut
son exécution prend beaucoup de temps, car
il peut s'agir d'extraire et de
décoder des données multimédias. Ainsi, comme c'est le cas pour
dont l'exécution peut prendre du temps, vous ne devez jamais l'appeler depuis votre
thread UI de l'application. Cela provoque le blocage de l'interface utilisateur jusqu'à ce que la méthode soit renvoyée,
ce qui est une très mauvaise expérience utilisateur et peut
provoquer une erreur ANR (L'application ne répond pas). Même si
vous vous attendez à ce que votre ressource se charge rapidement, n'oubliez pas que tout ce qui prend plus d'un dixième
d'une seconde pour répondre dans l'interface utilisateur entraîne une pause notable et donne
l'utilisateur l'impression que
votre application est lente.
Pour éviter de suspendre votre thread UI, générez un autre thread pour
préparer le MediaPlayer
et avertir le thread principal une fois l'opération terminée. Cependant, bien que
vous pouvez écrire la logique des threads
vous-même, ce modèle est si courant lors de l'utilisation de MediaPlayer
que le framework
fournit un moyen pratique d'accomplir cette tâche en utilisant
prepareAsync()
. Cette méthode
commence à préparer le contenu multimédia en arrière-plan et revient immédiatement. Lorsque le média
a fini de préparer, le onPrepared()
de MediaPlayer.OnPreparedListener
, configurée via
setOnPreparedListener()
est appelé.
Gérer l'état
Un autre aspect de MediaPlayer
que vous devez garder à l'esprit est
qu'elle est basée sur l'état. Autrement dit, MediaPlayer
a un état interne.
dont vous devez toujours être conscient lorsque vous écrivez votre code, car certaines opérations
ne sont valides que lorsque le joueur se trouve dans un état spécifique. Si vous effectuez une opération dans le
mauvais état, le système peut générer une exception ou provoquer d'autres comportements indésirables.
La documentation disponible dans
La classe MediaPlayer
montre un diagramme d'état complet.
qui précise quelles méthodes déplacent MediaPlayer
d'un état à un autre.
Par exemple, lorsque vous créez un nouveau MediaPlayer
, il se trouve dans l'état Inactif
de l'état. À ce stade, vous devez l'initialiser en appelant
setDataSource()
, c'est parti !
à l'état Initialisé. Vous devez ensuite le préparer en utilisant
prepare()
ou
prepareAsync()
. Quand ?
MediaPlayer
a terminé la préparation, il entre dans la classe Prepared
ce qui signifie que vous pouvez appeler start()
pour qu'elle lise le contenu multimédia. À ce stade, comme le montre le diagramme,
vous pouvez passer d'un état Started (Démarré), Suspendu (Mise en pause) à PlaybackCompleted (Lecture terminée) en procédant comme suit :
en appelant des méthodes telles que
start()
,
pause()
et
seekTo()
,
entre autres. Lorsque vous
appelez stop()
. Notez toutefois que
Impossible de rappeler start()
tant que vous n'aurez pas
préparer à nouveau MediaPlayer
.
Conservez toujours le diagramme d'état.
lorsque vous écrivez du code qui interagit avec
MediaPlayer
, car appeler ses méthodes à partir du mauvais état constitue
est la cause la plus courante de bugs.
Libérer MediaPlayer
Un MediaPlayer
peut consommer
ressources système.
Vous devez donc toujours prendre des précautions supplémentaires pour vous assurer
à une instance MediaPlayer
plus longtemps que nécessaire. Lorsque vous
vous devez toujours appeler
release()
pour vous assurer
les ressources système qui lui sont allouées sont correctement libérées. Par exemple, si vous
à l'aide d'un MediaPlayer
et que votre activité reçoit un appel à onStop()
, vous devez libérer le MediaPlayer
,
parce qu'il
qu'il n'est pas logique de le tenir tant que votre activité n'interagit pas avec
l'utilisateur (sauf si vous lisez du contenu multimédia en arrière-plan, ce qui est abordé dans la section suivante).
Lorsque votre activité reprend ou reprend, bien sûr, vous devez
Créez un MediaPlayer
et préparez-le à nouveau avant de reprendre la lecture.
Voici comment libérer et supprimer votre MediaPlayer
:
Kotlin
mediaPlayer?.release() mediaPlayer = null
Java
mediaPlayer.release(); mediaPlayer = null;
À titre d'exemple, considérez les problèmes
qui pourraient survenir si vous
oublié de libérer le MediaPlayer
lorsque votre activité est arrêtée, mais créez un
lorsque l'activité reprendra. Comme vous le savez peut-être, lorsque l'utilisateur modifie
l'orientation de l'écran (ou modifie la configuration de l'appareil d'une autre manière) ;
le système gère cela en redémarrant l'activité (par défaut). Ainsi, vous pouvez rapidement
consomment toutes les ressources système lorsque l'utilisateur
fait pivoter l'appareil entre les modes portrait et paysage, car à chaque
un changement d'orientation, vous créez un MediaPlayer
que vous n'avez jamais
de sortie. (Pour en savoir plus sur les redémarrages de l'environnement d'exécution, consultez Gérer les modifications apportées à l'environnement d'exécution.)
Vous vous demandez peut-être ce qui se passe si vous voulez continuer à jouer.
"contenu multimédia en arrière-plan" même lorsque l'utilisateur quitte votre activité, à peu près au même
du comportement de l'application Music intégrée. Dans ce cas, vous avez besoin
un MediaPlayer
contrôlé par un Service, comme
abordés dans la section suivante
Utiliser MediaPlayer dans un service
Si vous souhaitez lire vos contenus multimédias en arrière-plan même lorsque votre application
ne s'affiche pas à l'écran, c'est-à-dire que la lecture doit se poursuivre pendant que l'utilisateur
avec d'autres applications, vous devez lancer une
Service et contrôle
MediaPlayer
.
Vous devez intégrer le
MediaPlayer dans un service MediaBrowserServiceCompat
et
elle interagit avec
MediaBrowserCompat
dans une autre activité.
Vous devez faire attention à cette configuration client/serveur. Il y a des attentes sur la façon dont un lecteur exécuté dans un service d'arrière-plan interagit avec le reste du système d'exploitation. Si votre application ne répond pas à ces attentes, l'utilisateur peut ont une mauvaise expérience. Lue Créer une application audio pour en savoir plus.
Cette section décrit des instructions spéciales pour gérer un MediaPlayer lorsqu'il est implémenté dans un service.
Exécuter de manière asynchrone
Tout d'abord, comme une Activity
, fonctionnent toutes dans un
Service
est effectué dans un seul fil de discussion par
par défaut. En fait, si vous exécutez une activité et un service à partir de la même application,
utilisent le même thread (le "thread principal") par défaut. Par conséquent, les services doivent
traiter rapidement les intents entrants ;
et de ne jamais effectuer de longs calculs
pour y répondre. Si des
ou des appels bloquants sont attendus, vous devez effectuer ces tâches de manière asynchrone :
un autre fil de discussion que vous mettez en œuvre vous-même, ou en utilisant les nombreuses installations du framework
pour le traitement asynchrone.
Par exemple, lorsque vous utilisez un MediaPlayer
à partir de votre thread principal,
appelez prepareAsync()
plutôt que
prepare()
et implémenter
un MediaPlayer.OnPreparedListener
pour être averti lorsque la préparation est terminée et que vous pouvez commencer à jouer.
Exemple :
Kotlin
private const val ACTION_PLAY: String = "com.example.action.PLAY" class MyService: Service(), MediaPlayer.OnPreparedListener { private var mMediaPlayer: MediaPlayer? = null override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { ... val action: String = intent.action when(action) { ACTION_PLAY -> { mMediaPlayer = ... // initialize it here mMediaPlayer?.apply { setOnPreparedListener(this@MyService) prepareAsync() // prepare async to not block main thread } } } ... } /** Called when MediaPlayer is ready */ override fun onPrepared(mediaPlayer: MediaPlayer) { mediaPlayer.start() } }
Java
public class MyService extends Service implements MediaPlayer.OnPreparedListener { private static final String ACTION_PLAY = "com.example.action.PLAY"; MediaPlayer mediaPlayer = null; public int onStartCommand(Intent intent, int flags, int startId) { ... if (intent.getAction().equals(ACTION_PLAY)) { mediaPlayer = ... // initialize it here mediaPlayer.setOnPreparedListener(this); mediaPlayer.prepareAsync(); // prepare async to not block main thread } } /** Called when MediaPlayer is ready */ public void onPrepared(MediaPlayer player) { player.start(); } }
Gérer les erreurs asynchrones
Pour les opérations synchrones, les erreurs
être signalée par une exception ou un code d'erreur, mais chaque fois que vous utilisez des requêtes
ressources, vous devez vous assurer que votre application est informée
d'erreurs en conséquence. Dans le cas d'une MediaPlayer
,
vous pouvez y parvenir en implémentant
MediaPlayer.OnErrorListener
et
en le définissant dans votre instance MediaPlayer
:
Kotlin
class MyService : Service(), MediaPlayer.OnErrorListener { private var mediaPlayer: MediaPlayer? = null fun initMediaPlayer() { // ...initialize the MediaPlayer here... mediaPlayer?.setOnErrorListener(this) } override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean { // ... react appropriately ... // The MediaPlayer has moved to the Error state, must be reset! } }
Java
public class MyService extends Service implements MediaPlayer.OnErrorListener { MediaPlayer mediaPlayer; public void initMediaPlayer() { // ...initialize the MediaPlayer here... mediaPlayer.setOnErrorListener(this); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { // ... react appropriately ... // The MediaPlayer has moved to the Error state, must be reset! } }
Il est important de se rappeler que lorsqu'une erreur se produit, MediaPlayer
passe à l'état Erreur (consultez la documentation pour
MediaPlayer
pour le diagramme d'état complet)
et vous devez le réinitialiser avant
de pouvoir l'utiliser à nouveau.
Utiliser des wakelocks
Lors de la conception d'applications qui lisent des contenus multimédias en arrière-plan, l'appareil peut se mettre en veille pendant l'exécution de votre service. Comme le système Android tente de préserver de la batterie lorsque l'appareil est en veille, le système tente d'éteindre fonctionnalités du téléphone qui sont pas nécessaires, y compris le CPU et le matériel WiFi. Toutefois, si votre service lit ou diffuse de la musique en streaming, vous devez empêcher empêcher le système d'interférer avec la lecture.
Afin de garantir que votre service continue de fonctionner en ces conditions, vous devez utiliser des « wakelocks ». Un wakelock est un moyen de signaler le système sur lequel votre application utilise une fonctionnalité restent disponibles même si le téléphone est inactif.
Remarque:Vous devez toujours utiliser les wakelocks avec parcimonie et les maintenir enfoncés. aussi longtemps que nécessaire, car ils réduisent considérablement l'autonomie de la batterie appareil.
Pour garantir que le processeur continue de s'exécuter pendant que votre MediaPlayer
est
appelez la méthode setWakeMode()
lors de l'initialisation de votre MediaPlayer
. Une fois que c'est fait,
le MediaPlayer
maintient le verrouillage spécifié pendant la lecture et libère le verrou
en cas de pause ou d'arrêt:
Kotlin
mediaPlayer = MediaPlayer().apply { // ... other initialization here ... setWakeMode(applicationContext, PowerManager.PARTIAL_WAKE_LOCK) }
Java
mediaPlayer = new MediaPlayer(); // ... other initialization here ... mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
Cependant, le wakelock acquis dans cet exemple garantit uniquement que le processeur reste actif. Si
vous diffusez du contenu multimédia
et que vous utilisez une connexion Wi-Fi, vous voudrez probablement
WifiLock
en tant que
que vous devez acquérir et publier manuellement. Lorsque vous commencerez à préparer
MediaPlayer
par l'URL distante, vous devez créer et obtenir le verrou Wi-Fi.
Exemple :
Kotlin
val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiLock: WifiManager.WifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock") wifiLock.acquire()
Java
WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE)) .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock"); wifiLock.acquire();
Lorsque vous mettez en pause ou arrêtez la lecture d'un contenu multimédia, ou lorsque vous n'avez plus besoin de la vous devez débloquer le verrou:
Kotlin
wifiLock.release()
Java
wifiLock.release();
Nettoyage...
Comme indiqué précédemment, un objet MediaPlayer
peut consommer
de ressources système. Vous ne devez donc les conserver que pendant la durée
release()
lorsque vous n'en avez plus besoin. C'est important
d'appeler cette méthode de nettoyage explicitement au lieu d'utiliser la récupération de mémoire du système, car
il peut s'écouler un certain temps avant que le récupérateur de mémoire récupère le MediaPlayer
,
car il n’est sensible qu’aux besoins de mémoire et non à la pénurie d’autres ressources liées aux médias.
Ainsi, lorsque vous utilisez un service, vous devez toujours remplacer
onDestroy()
pour vous assurer de publier votre application
MediaPlayer
:
Kotlin
class MyService : Service() { private var mediaPlayer: MediaPlayer? = null // ... override fun onDestroy() { super.onDestroy() mediaPlayer?.release() } }
Java
public class MyService extends Service { MediaPlayer mediaPlayer; // ... @Override public void onDestroy() { super.onDestroy(); if (mediaPlayer != null) mediaPlayer.release(); } }
Pensez toujours à rechercher d'autres opportunités de publier votre MediaPlayer
ainsi que lors de l'arrêt. Par exemple, si vous ne vous attendez pas à
de pouvoir lire des contenus multimédias pendant une période prolongée (après avoir perdu la priorité sur le son, par exemple) ;
vous devez absolument libérer votre MediaPlayer
existante et la recréer
plus tard. Le
En revanche, si vous prévoyez d'arrêter la lecture pendant un court laps de temps, vous devriez
conserver votre MediaPlayer
pour éviter les frais de création et de préparation
à nouveau.
Gestion des droits numériques (DRM)
À partir d'Android 8.0 (niveau d'API 26), MediaPlayer
inclut des API qui :
permettre la lecture de contenus protégés par DRM ; Elles sont semblables à l'API de bas niveau fournie par
MediaDrm
, mais elles fonctionnent à un niveau plus élevé et ne fonctionnent pas
expose les objets extracteurs, drm et crypto sous-jacents.
Bien que l'API MediaPlayer DRM ne fournisse pas toutes les fonctionnalités
MediaDrm
, il est compatible avec les cas d'utilisation les plus courants. La
la mise en œuvre actuelle peut gérer les types de contenu suivants:
- Fichiers multimédias locaux protégés par Widevine
- Fichiers multimédias distants/en streaming protégés par Widevine
L'extrait de code suivant montre comment utiliser le nouveau MediaPlayer DRM. dans une implémentation synchrone simple.
Pour gérer les contenus multimédias contrôlés par DRM, vous devez inclure les nouvelles méthodes en plus de le flux habituel des appels MediaPlayer, comme indiqué ci-dessous:
Kotlin
mediaPlayer?.apply { setDataSource() setOnDrmConfigHelper() // optional, for custom configuration prepare() drmInfo?.also { prepareDrm() getKeyRequest() provideKeyResponse() } // MediaPlayer is now ready to use start() // ...play/pause/resume... stop() releaseDrm() }
Java
setDataSource(); setOnDrmConfigHelper(); // optional, for custom configuration prepare(); if (getDrmInfo() != null) { prepareDrm(); getKeyRequest(); provideKeyResponse(); } // MediaPlayer is now ready to use start(); // ...play/pause/resume... stop(); releaseDrm();
Commencez par initialiser l'objet MediaPlayer
et définissez
sa source à l'aide de setDataSource()
,
comme d'habitude. Ensuite, pour utiliser DRM, procédez comme suit:
- Si vous souhaitez que votre application effectue une configuration personnalisée, définissez
OnDrmConfigHelper
, puis associez-la au joueur utilisantsetOnDrmConfigHelper()
- Appelez
prepare()
. - Appelez
getDrmInfo()
. Si la source est protégée par DRM contenu, la méthode renvoie une valeur non nulle ValeurMediaPlayer.DrmInfo
.
Si MediaPlayer.DrmInfo
existe:
- Examinez la carte des UUID disponibles et choisissez-en un.
- Préparez la configuration DRM pour la source actuelle en appelant
prepareDrm()
. - Si vous avez créé et enregistré un
OnDrmConfigHelper
, il s'appelle alors queprepareDrm()
est en cours d'exécution. Cela vous permet d'effectuer une configuration personnalisée de la DRM. avant d'ouvrir la session DRM. Le rappel est appelé de manière synchrone dans le thread qui a appeléprepareDrm()
À accéder aux propriétés DRM,getDrmPropertyString()
etsetDrmPropertyString()
Évitez les opérations interminables. - Si l'appareil n'a pas encore été provisionné,
prepareDrm()
également accède au serveur de provisionnement pour provisionner l'appareil. Cela peut prendre de temps variable, en fonction de la connectivité réseau. - Pour obtenir un tableau d'octets de requête de clé opaque à envoyer à un serveur de licences, appelez
getKeyRequest()
- Pour informer le moteur DRM de la réponse clé reçue du serveur de licences, appelez
provideKeyResponse()
Le résultat dépend du type de requête de clé: <ph type="x-smartling-placeholder">- </ph>
- Si la réponse concerne une requête de clé hors connexion, le résultat est un identifiant de collection de clés. Vous pouvez utiliser
cet identifiant d'ensemble de clés avec
restoreKeys()
pour restaurer les clés session. - Si la réponse concerne une requête de streaming ou de publication, le résultat est nul.
- Si la réponse concerne une requête de clé hors connexion, le résultat est un identifiant de collection de clés. Vous pouvez utiliser
cet identifiant d'ensemble de clés avec
Exécuter prepareDrm()
de manière asynchrone
Par défaut, prepareDrm()
s'exécute de manière synchrone, en bloquant l'opération jusqu'à la fin de la préparation. Cependant,
la première préparation de la DRM sur un nouvel appareil peut également nécessiter un provisionnement, ce qui
gérées en interne par
prepareDrm()
et
peut prendre un certain temps
en raison de l'opération réseau impliquée. Vous pouvez
évitez de bloquer
prepareDrm()
par
définir et définir un MediaPlayer.OnDrmPreparedListener
.
Lorsque vous définissez un OnDrmPreparedListener
,
prepareDrm()
effectue le provisionnement (si nécessaire) et la préparation en arrière-plan. Quand ?
le provisionnement et la préparation sont terminés, l'écouteur est appelé. Vous devez
ne faites aucune hypothèse concernant la séquence d'appel ou le thread dans lequel
s'exécute (sauf si l'écouteur est enregistré avec un thread de gestionnaire).
L'écouteur peut être appelé avant ou après
prepareDrm()
.
Configurer la DRM de manière asynchrone
Vous pouvez initialiser la DRM de manière asynchrone en créant et en enregistrant le
MediaPlayer.OnDrmInfoListener
pour la préparation DRM et les
MediaPlayer.OnDrmPreparedListener
pour démarrer le lecteur.
Elles fonctionnent conjointement avec
prepareAsync()
, comme indiqué ci-dessous:
Kotlin
setOnPreparedListener() setOnDrmInfoListener() setDataSource() prepareAsync() // ... // If the data source content is protected you receive a call to the onDrmInfo() callback. override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) { mediaPlayer.apply { prepareDrm() getKeyRequest() provideKeyResponse() } } // When prepareAsync() finishes, you receive a call to the onPrepared() callback. // If there is a DRM, onDrmInfo() sets it up before executing this callback, // so you can start the player. override fun onPrepared(mediaPlayer: MediaPlayer) { mediaPlayer.start() }
Java
setOnPreparedListener(); setOnDrmInfoListener(); setDataSource(); prepareAsync(); // ... // If the data source content is protected you receive a call to the onDrmInfo() callback. onDrmInfo() { prepareDrm(); getKeyRequest(); provideKeyResponse(); } // When prepareAsync() finishes, you receive a call to the onPrepared() callback. // If there is a DRM, onDrmInfo() sets it up before executing this callback, // so you can start the player. onPrepared() { start(); }
Gérer les contenus multimédias chiffrés
À partir d'Android 8.0 (niveau d'API 26), MediaPlayer
peut également déchiffrer
Schéma CENC (Common Encryption Scheme) et
Contenu multimédia chiffré au niveau de l'échantillon HLS (Méthodes=EXEMPLE-AES) pour les types de flux élémentaires
H.264 et AAC. Auparavant, le contenu multimédia chiffré en segment complet (méthode method=AES-128) était accepté.
Récupérer des contenus multimédias à partir d'un ContentResolver
Une autre fonctionnalité qui peut être utile
dans une application de lecteur multimédia est la possibilité
récupérer la musique dont
l'utilisateur dispose sur l'appareil. Pour ce faire, interrogez ContentResolver
pour rechercher des supports externes:
Kotlin
val resolver: ContentResolver = contentResolver val uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI val cursor: Cursor? = resolver.query(uri, null, null, null, null) when { cursor == null -> { // query failed, handle error. } !cursor.moveToFirst() -> { // no media on the device } else -> { val titleColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE) val idColumn: Int = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID) do { val thisId = cursor.getLong(idColumn) val thisTitle = cursor.getString(titleColumn) // ...process entry... } while (cursor.moveToNext()) } } cursor?.close()
Java
ContentResolver contentResolver = getContentResolver(); Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Cursor cursor = contentResolver.query(uri, null, null, null, null); if (cursor == null) { // query failed, handle error. } else if (!cursor.moveToFirst()) { // no media on the device } else { int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE); int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID); do { long thisId = cursor.getLong(idColumn); String thisTitle = cursor.getString(titleColumn); // ...process entry... } while (cursor.moveToNext()); }
Pour l'utiliser avec MediaPlayer
, procédez comme suit:
Kotlin
val id: Long = /* retrieve it from somewhere */ val contentUri: Uri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id ) mediaPlayer = MediaPlayer().apply { setAudioAttributes( AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ) setDataSource(applicationContext, contentUri) } // ...prepare and start...
Java
long id = /* retrieve it from somewhere */; Uri contentUri = ContentUris.withAppendedId( android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioAttributes( new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA) .build() ); mediaPlayer.setDataSource(getApplicationContext(), contentUri); // ...prepare and start...
En savoir plus
Ces pages traitent de sujets liés à l'enregistrement, au stockage et à la lecture de contenus audio et vidéo.