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.

Il arrive parfois que deux applications ou plus souhaitent "capturer" la même entrée audio. Ils peuvent effectuer des tâches différentes. Par exemple, certaines applications qui reçoivent du contenu audio peuvent effectuer un "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 souhaitent recevoir une entrée audio. Sur cette page, nous utilisons le terme "capture", qu'une application enregistre ou écoute simplement.

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

Comportement antérieur à 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 ou écoutait déjà du contenu audio, elle pouvait créer un objet AudioRecord, mais une erreur serait renvoyée lorsque vous appeliez AudioRecord.startRecording() et que l'enregistrement ne démarrerait pas.

Une exception à cette règle concernait les cas où 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 lancer l'enregistrement. Dans ce cas, 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) pouvaient capturer l'entrée audio. Lorsqu'une application sans service de premier plan ni composant d'UI de premier plan commençait à effectuer une capture, elle continuait de s'exécuter, mais recevait du silence, même s'il s'agissait de la seule application à capturer du contenu audio à l'époque.

Comportement d'Android 10

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

Android 10 impose un schéma de priorité qui peut basculer le flux audio d'entrée entre les applications lorsqu'elles sont en cours d'exécution. Dans la plupart des cas, si une nouvelle application acquiert l'entrée audio, l'application précédemment capturée continue de s'exécuter, mais reçoit du silence. Dans certains cas, le système peut continuer à fournir 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. Toutefois, la priorité audio est gérée par des requêtes programmatiques visant à obtenir et à libérer la sélection, tandis que le schéma de changement d'entrée décrit ici est basé sur une règle de priorisation appliquée automatiquement lorsqu'une nouvelle application commence à capturer du contenu audio.

Pour la capture audio, Android distingue deux types d'applications:

  • Les applications "ordinaires" sont installées par l'utilisateur.
  • Les applications "privilégées" sont préinstallées sur l'appareil. y compris 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.

Voici les règles de priorisation pour l'utilisation et le partage des entrées audio:

  • 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 enregistrent du contenu audio à partir d'une source sensible à la confidentialité ont une priorité plus élevée que les autres.
  • Deux applications ordinaires ne peuvent jamais enregistrer du son en même temps.
  • Dans certaines situations, une application privilégiée peut partager l'entrée audio avec une autre application.
  • Si deux applications d'arrière-plan de même priorité capturent du contenu audio, la dernière application lancée a une priorité plus élevée.

Scénarios de partage

Lorsque deux applications tentent d'enregistrer du contenu audio, elles peuvent toutes les deux recevoir le signal d'entrée, ou l'une d'elles peut recevoir le silence.

Il existe quatre scénarios principaux:

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

Assistant + application standard

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

Android partage l'audio d'entrée selon les règles suivantes:

  • L'Assistant peut recevoir du contenu audio (qu'il soit au premier plan ou en arrière-plan) sauf si une autre application utilisant une source audio sensible à la confidentialité est déjà en train d'effectuer une capture.

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

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

Service d'accessibilité + application ordinaire

Une AccessibilityService nécessite une déclaration stricte.

Android partage l'audio d'entrée selon les règles suivantes:

  • Si l'UI du service est en haut, 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, ce scénario est traité comme le cas ordinaire de deux applications ci-dessous.

Deux applications ordinaires

Lorsque deux applications effectuent la capture simultanée, une seule reçoit le contenu audio et l'autre reçoit le son.

Android partage l'audio d'entrée selon les règles suivantes:

  • Si aucune des applications n'est sensible à la confidentialité, l'application surmontée d'une UI reçoit du contenu audio. Si aucune des deux applications n'a d'interface utilisateur, celle qui a commencé à capturer le plus récemment reçoit du contenu audio.
  • Si l'une des applications est sensible à la confidentialité, elle reçoit du contenu audio et l'autre application obtient le son, même si elle dispose d'une interface utilisateur ou a commencé la capture plus récemment.
  • Si les deux applications sont sensibles à la confidentialité, l'application qui a commencé à capturer le contenu le plus récemment reçoit du contenu audio, tandis que l'autre reçoit le son.

Appel vocal + application standard

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 selon les règles suivantes:

Comportement d'Android 11

Android 11 (niveau d'API 30) respecte le schéma de priorités d'Android 10 décrit ci-dessus. Il fournit également de nouvelles méthodes dans AudioRecord, MediaRecorder et AAudioStream qui activent et désactivent la possibilité de capturer du contenu audio simultanément, 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 capturent du contenu audio simultanément, seules une ou deux d'entre elles sont "actives" (recevant du contenu audio), tandis que les autres sont coupées (le silence). Lorsque les applications actives changent, le framework audio peut reconfigurer les chemins audio selon les 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 ayant la priorité la plus élevée est activé. Tous les autres prétraitements sont ignorés.

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

  • Capturer avec ou sans mise sous silence
  • Appareil modifié
  • Prétraitement modifié
  • Propriétés du flux modifiées (taux d'échantillonnage, masque de canal, format d'échantillon)

Vous devez appeler AudioRecord.registerAudioRecordingCallback() avant de démarrer 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. Pour en savoir plus sur ce changement, utilisez les méthodes suivantes:

isClientSilenced()
Renvoie la valeur "true" si le son 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 dont la priorité est la plus élevée.
getFormat()
Renvoie les propriétés du flux. Notez que les données audio réelles reçues par le client respectent toujours le format requis renvoyé par getClientFormat(). Le framework effectue automatiquement le rééchantillonnage, le canal et la conversion de format nécessaires, du format utilisé au niveau de l'interface matérielle vers le format spécifié par le client.
AudioRecord.getActiveRecordingConfiguration().
Renvoie la configuration d'enregistrement active.

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