À partir d'Android 17 QPR1 (niveau d'API 37.1 ou Build.VERSION_CODES_FULL.CINNAMON_BUN_1), Android introduit la prise en charge de plate-forme pour l'encodage Extended High Efficiency Advanced Audio Coding (xHE-AAC).
Défini dans les normes ISO/IEC 23003-3 (MPEG-D USAC) et ISO/IEC 23003-4 (MPEG-D DRC), xHE-AAC combine le codage audio et vocal unifié avec la normalisation obligatoire du volume sonore et le contrôle intégré de la plage dynamique. Bien que le décodage xHE-AAC soit pris en charge et obligatoire dans le document de définition de compatibilité Android (CDD) pour plusieurs versions de la plate-forme, l'ajout d'un encodeur xHE-AAC (implémentations matérielles c2.android.xheaac.encoder et OEM) vous permet d'enregistrer des messages vocaux et audio à faible débit, des flux audio en direct et des charges utiles de communication avec une clarté vocale supérieure et un volume constant sur tous les appareils.
Avantages du xHE-AAC
L'enregistrement vocal traditionnel dans les applications de messagerie Android utilise généralement l'ancien format AAC-LC (AAC Low Complexity) à 28 kbit/s. À de faibles débits (< 32 kbit/s), AAC-LC présente des artefacts de limitation de bande perceptibles, une qualité vocale floue et une efficacité de compression sous-optimale. Pour les utilisateurs finaux, cela se traduit par un son étouffé et métallique, où les consonnes sont difficiles à distinguer, ce qui oblige les auditeurs à réécouter les messages ou à faire des efforts pour comprendre la parole dans les environnements bruyants. De plus, les niveaux de volume incohérents entre les extraits vocaux obligent les utilisateurs à ajuster fréquemment le volume de l'appareil.
xHE-AAC surmonte ces limites en appliquant des algorithmes de codage audio plus avancés, par exemple en basculant dynamiquement entre des outils de codage vocal dédiés et des outils de codage audio généraux, tout en étendant la gamme de fréquences avec la réplication de bande spectrale améliorée (eSBR) et en offrant une capacité de codage stéréo paramétrique avec très peu de surcharge de codage supplémentaire.
Le DRC MPEG-D intégré fournit un contrôle obligatoire du volume pour le xHE-AAC afin de lire le contenu à un volume constant et offre un traitement de contrôle de la plage dynamique pour offrir la meilleure expérience utilisateur possible pour l'écoute sur n'importe quelle plate-forme et dans n'importe quel environnement.
Cas d'utilisation cibles
- Services de communication enrichis (RCS) et messagerie vocale : conforme à la version 3.1 et aux versions ultérieures du profil universel GSMA RCC.71, qui impose le format xHE-AAC pour la messagerie audio à faible débit binaire.
- Streaming audio en direct et podcasts : offre une qualité audio résiliente sur les connexions réseau mobile ou satellite dégradées.
Disponibilité de la plate-forme (niveau d'API 37.1 et versions ultérieures)
L'encodage xHE-AAC sur la plate-forme nécessite le niveau d'API 37.1 (Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1/SDK 3700001 ou version ultérieure).
Requête pour la prise en charge de l'encodeur xHE-AAC
Vous ne devez pas supposer que l'encodage xHE-AAC est disponible sur tous les appareils en appelant MediaCodec.createByCodecName(...) avec "c2.android.xheaac.encoder".
- Certains appareils peuvent fournir un encodeur xHE-AAC à accélération matérielle du fournisseur du chipset plutôt que l'encodeur logiciel de la plate-forme.
- Les anciennes versions de l'OS ou les ROM personnalisées ne sont pas compatibles avec l'encodage xHE-AAC.
- Avant d'encoder une pièce jointe pour la messagerie peer-to-peer (comme RCS ou le chat), les applications doivent également vérifier si le client de réception annonce la prise en charge du décodage USAC/xHE-AAC (par exemple, à l'aide de la découverte des capacités SDP
profile-level-id=55/object=42) pour éviter les échecs d'interopérabilité sur les anciens récepteurs.
Inspecter les capacités de MediaCodecList
Pour vérifier si l'appareil actuel est compatible avec l'encodage xHE-AAC, inspectez le profileLevels des encodeurs compatibles avec MediaFormat.MIMETYPE_AUDIO_AAC :
Kotlin
import android.media.MediaCodecInfo.CodecProfileLevel import android.media.MediaCodecList import android.media.MediaFormat import android.os.Build /** * Checks if the current device supports xHE-AAC audio encoding. */ fun isXheAacEncodingSupported(): Boolean { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false } val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) for (codecInfo in codecList.codecInfos) { if (!codecInfo.isEncoder) continue if (MediaFormat.MIMETYPE_AUDIO_AAC in codecInfo.supportedTypes) { val capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC) // Check if AACObjectXHE (42) is present in profileLevels val supportsXhe = capabilities.profileLevels.any { profileLevel -> profileLevel.profile == CodecProfileLevel.AACObjectXHE } if (supportsXhe) { return true } } } return false }
Java
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; /** * Checks if the current device supports xHE-AAC audio encoding. */ public boolean isXheAacEncodingSupported() { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false; } MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) { if (!codecInfo.isEncoder()) continue; for (String type : codecInfo.getSupportedTypes()) { if (MediaFormat.MIMETYPE_AUDIO_AAC.equals(type)) { MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC); for (CodecProfileLevel profileLevel : capabilities.profileLevels) { if (profileLevel.profile == CodecProfileLevel.AACObjectXHE) { return true; } } } } } return false; }
Configurer et instancier l'encodeur xHE-AAC
Une fois que vous avez vérifié la compatibilité avec xHE-AAC, configurez votre MediaFormat avec KEY_AAC_PROFILE défini sur MediaCodecInfo.CodecProfileLevel.AACObjectXHE (valeur 42).
Kotlin
fun setupXheAacEncoder(): MediaCodec? { if (!isXheAacEncodingSupported()) { return null } val mimeType = MediaFormat.MIMETYPE_AUDIO_AAC val sampleRate = 48000 val channelCount = 1 // Mono voice recording val bitRate = 20000 // 20 kbps delivers superior speech clarity val format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount).apply { setInteger(MediaFormat.KEY_BIT_RATE, bitRate) setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE) } // Find the hardware or software encoder supporting this format and profile val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) val encoderName = codecList.findEncoderForFormat(format) ?: return null val encoder = MediaCodec.createByCodecName(encoderName) encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) return encoder }
Java
public MediaCodec setupXheAacEncoder() throws IOException { if (!isXheAacEncodingSupported()) { return null; } String mimeType = MediaFormat.MIMETYPE_AUDIO_AAC; int sampleRate = 48000; int channelCount = 1; // Mono voice recording int bitRate = 20000; // 20 kbps delivers superior speech clarity MediaFormat format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE); // Find the hardware or software encoder supporting this format and profile MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); String encoderName = codecList.findEncoderForFormat(format); if (encoderName == null) { return null; } MediaCodec encoder = MediaCodec.createByCodecName(encoderName); encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); return encoder; }
Limites des logiciels d'encodage compatibles (c2.android.xheaac.encoder)
Lorsque vous utilisez l'encodeur logiciel xHE-AAC fourni par le système (c2.android.xheaac.encoder), le composant annonce les limites de capacité suivantes :
- Nombre de canaux : jusqu'à
2canaux (mono / stéréo). - Taux d'échantillonnage :
44100 Hz,48000 Hz. - Plage de débit : de
12,000 bpsà400,000 bps(12 kbit/s à 400 kbit/s). - Multiplexage de conteneur : compatible avec les flux élémentaires MP4A bruts et le multiplexage de conteneur MP4/M4A de la plate-forme (
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4).