Partage de l'entrée audio

L'entrée audio provient généralement du micro intégré, d'un micro externe ou d'une interface audio connectée à l'appareil. L'entrée audio peut également provenir d'une conversation téléphonique.

Parfois, plusieurs applications peuvent vouloir "capturer" la même entrée audio. Ils peuvent effectuer des tâches différentes. Par exemple, certaines applications qui reçoivent du son peuvent être "en cours d'enregistrement" (comme un simple enregistreur vocal), tandis que d'autres peuvent "écouter" (comme l'Assistant Google ou un service d'accessibilité qui répond aux commandes vocales).

Dans les deux cas, ces applications veulent recevoir une entrée audio. Sur cette page, nous utilisons le terme "capturer", qu'une application soit en train d'enregistrer ou seulement d'écouter.

Si plusieurs applications souhaitent capturer du contenu audio en même temps, il peut y avoir un problème lors de l'envoi du signal audio de la même source à toutes les applications. Cette page explique comment le système Android partage l'entrée audio entre plusieurs applications qui capturent du contenu audio.

Comportement des versions antérieures à Android 10

Avant Android 10, le flux audio d'entrée ne pouvait être capturé que par une application à la fois. Si une application enregistrait déjà ou écoutait du contenu audio, elle peut créer un objet AudioRecord, mais une erreur est renvoyée lorsque vous appelez AudioRecord.startRecording() et que l'enregistrement ne démarre pas.

Il existe une exception à cette règle lorsqu'une application privilégiée (comme l'Assistant Google ou un service d'accessibilité) disposait de l'autorisation android.permission.CAPTURE_AUDIO_HOTWORD et utilisait une source audio de type HOTWORD. Dans ce cas, une autre application peut démarrer l'enregistrement. Lorsque cela s'est produit, l'application privilégiée s'est arrêtée et la nouvelle application a capturé l'entrée.

Une autre modification a été ajoutée dans Android 9: seules les applications exécutées au premier plan (ou un service de premier plan) peuvent capturer l'entrée audio. Lorsqu'une application sans service de premier plan ni composant d'interface utilisateur au premier plan commençait à enregistrer, l'application continuait de s'exécuter, mais recevait du silence, même s'il s'agissait de la seule application à capturer du contenu audio à ce moment-là.

Comportement d'Android 10

Avant Android 10, le comportement est le suivant : "premier arrivé, premier servi". Une fois qu'une application commence à enregistrer du contenu audio, aucune autre application ne peut accéder à l'entrée audio tant que l'application qui capture le contenu audio n'est pas arrêtée.

Android 10 impose un schéma de priorité qui peut basculer le flux audio d'entrée entre les applications pendant leur exécution. Dans la plupart des cas, si une nouvelle application acquiert l'entrée audio, l'application de capture précédente continue de s'exécuter, mais reçoit du silence. Dans certains cas, le système peut continuer à diffuser du contenu audio aux deux applications. Les différents scénarios de partage sont expliqués ci-dessous.

Ce schéma est semblable à la façon dont le ciblage audio gère plusieurs applications en concurrence pour l'utilisation de la sortie audio. Cependant, la priorité audio est gérée par des requêtes programmatiques pour obtenir et libérer la priorité, tandis que le schéma de changement d'entrée décrit ici est basé sur une règle de priorisation qui est appliquée automatiquement chaque fois qu'une nouvelle application commence à enregistrer du contenu audio.

Pour les besoins de capture audio, Android distingue deux types d'applications:

  • Les applications "ordinaires" sont installées par l'utilisateur.
  • Les applications privilégiées sont préinstallées sur l'appareil. Cela inclut l'Assistant Google et tous les services d'accessibilité.

En outre, une application est traitée différemment si elle utilise une source audio "sensible à la confidentialité" : CAMCORDER ou VOICE_COMMUNICATION.

Les règles de priorisation d'utilisation et de partage des entrées audio sont les suivantes:

  • Les applications privilégiées ont une priorité plus élevée que les applications ordinaires.
  • Les applications dont l'interface utilisateur au premier plan est visible ont une priorité plus élevée que les applications en arrière-plan.
  • Les applications qui capturent du contenu audio à partir d'une source sensible à la confidentialité sont prioritaires sur les applications qui ne le sont pas.
  • Deux applications ordinaires ne peuvent jamais capturer le son en même temps.
  • Dans certains cas, une application privilégiée peut partager une entrée audio avec une autre application.
  • Si deux applications en arrière-plan ayant la même priorité captent du contenu audio, la dernière lancée a une priorité plus élevée.

Scénarios de partage

Lorsque deux applications tentent de capturer du contenu audio, elles peuvent toutes les deux recevoir le signal d'entrée, ou l'une d'entre elles peut être mise sous silence.

Il existe quatre scénarios principaux:

  • Assistant + application ordinaire
  • Service d'accessibilité + application ordinaire
  • Deux applications ordinaires
  • Appel vocal + application ordinaire

Assistant + application ordinaire

L'Assistant est une application privilégiée, car elle est préinstallée et détient le rôle RoleManager.ROLE_ASSISTANT. Toute autre application préinstallée ayant ce rôle est traitée de la même manière.

Android partage l'audio d'entrée conformément aux règles suivantes:

  • L'Assistant peut recevoir du son (qu'il soit au premier plan ou en arrière-plan), sauf si une autre application utilisant une source audio respectueuse de la confidentialité est déjà en train de l'enregistrer.

  • L'application reçoit du contenu audio, sauf si l'Assistant dispose d'un composant d'interface utilisateur visible en haut de l'écran.

Notez que les deux applications ne reçoivent de l'audio que lorsque l'Assistant est en arrière-plan et que l'autre application ne capture pas l'écran à partir d'une source audio sensible à la confidentialité.

Service d'accessibilité + application ordinaire

Un AccessibilityService nécessite une déclaration stricte.

Android partage l'audio d'entrée conformément aux règles suivantes:

  • Si l'interface utilisateur du service se trouve au-dessus, le service et l'application reçoivent tous deux une entrée audio. Ce comportement offre des fonctionnalités telles que le contrôle d'un appel vocal ou d'une capture vidéo à l'aide de commandes vocales.

  • Si le service n'est pas en haut de la page, ce cas est considéré comme le cas ordinaire à deux applications ci-dessous.

Deux applications ordinaires

Lorsque deux applications capturent simultanément, une seule application reçoit le son et l'autre reçoit le silence.

Android partage l'audio d'entrée conformément aux règles suivantes:

  • Si aucune application n'est sensible à la confidentialité, celle avec une UI en haut reçoit l'audio. Si aucune des applications ne dispose d'interface utilisateur, celle qui a commencé à enregistrer le dernier enregistrement audio reçoit des données audio.
  • Si l'une des applications est sensible à la confidentialité, elle reçoit des contenus audio, et l'autre application est mise sous silence, même si une interface utilisateur est affichée en haut de l'écran ou si la capture a commencé plus récemment.
  • Si les deux applications sont sensibles à la confidentialité, celle qui a commencé à enregistrer le plus récemment reçoit le son et l'autre reçoit le silence.

Appel vocal + application ordinaire

Un appel vocal est actif si le mode audio renvoyé par AudioManager.getMode() est MODE_IN_CALL ou MODE_IN_COMMUNICATION.

Android partage l'audio d'entrée conformément aux règles suivantes:

Comportement d'Android 11

Android 11 (niveau d'API 30) respecte le schéma de priorité Android 10 décrit ci-dessus. Elle fournit également de nouvelles méthodes dans AudioRecord, MediaRecorder et AAudioStream, qui permettent d'activer et de désactiver la capture audio simultanée, quel que soit le cas d'utilisation sélectionné.

Les nouvelles méthodes sont les suivantes:

Lorsque setPrivacySensitive() est défini sur true, le cas d'utilisation de la capture est privé et même un Assistant privilégié ne peut pas effectuer de capture simultanément. Ce paramètre ignore le comportement par défaut qui dépend de la source audio. Par exemple, VOICE_COMMUNICATION est privé par défaut, mais UNPROCESSED ne l'est pas.

Modifications de configuration

Lorsque plusieurs applications captent du contenu audio simultanément, une ou deux d'entre elles sont "actives" (réception du contenu audio). Le son des autres applications est coupé (c'est-à-dire qu'elles reçoivent du son). Lorsque les applications actives changent, le framework audio peut reconfigurer les chemins audio en fonction des règles suivantes:

  • Le périphérique d'entrée audio de chaque application active peut changer (par exemple, passer du micro intégré à un casque Bluetooth connecté).
  • Le prétraitement associé à l'application active à la priorité la plus élevée est activé. Tout autre prétraitement est ignoré.

Étant donné qu'une application active peut être mise sous silence lorsqu'une application de priorité supérieure devient active, vous pouvez enregistrer un AudioManager.AudioRecordingCallback sur l'objet AudioRecord ou MediaRecorder pour être averti lorsque la configuration change. Voici les modifications possibles:

  • Capture d'écran mise sous silence ou non
  • Appareil modifié
  • La valeur Prétraitement a été modifiée.
  • Propriétés de flux modifiées (taux d'échantillonnage, masque de chaîne, format d'échantillon)

Vous devez appeler AudioRecord.registerAudioRecordingCallback() avant de commencer la capture. Le rappel n'est exécuté que lorsque l'application reçoit du contenu audio et qu'un changement se produit.

La méthode onRecordingConfigChanged() renvoie un AudioRecordingConfiguration contenant l'état actuel de la capture audio. Utilisez les méthodes suivantes pour en savoir plus sur la modification:

isClientSilenced()
Renvoie la valeur "true" si le son renvoyé au client est actuellement mis sous silence en raison de la règle de capture.
getAudioDevice()
Renvoie l'appareil audio actif.
getEffects()
Renvoie l'effet de prétraitement actif. Notez que l'effet actif peut être différent de ceux renvoyés par getClientEffects() si le client n'est pas l'application active ayant la priorité la plus élevée.
getFormat()
Renvoie les propriétés du flux. Notez que les données audio reçues par le client respectent toujours le format requis renvoyé par getClientFormat(). Le framework effectue automatiquement le rééchantillonnage, les canaux et la conversion du format requis entre le format utilisé dans l'interface matérielle et celui spécifié par le client.
AudioRecord.getActiveRecordingConfiguration().
Renvoie la configuration d'enregistrement actif.

Vous pouvez obtenir une vue générale de tous les enregistrements actifs sur l'appareil en appelant AudioManager.getActiveRecordingConfigurations().