Actualités sur les produits

Au-delà des fonctionnalités individuelles : garantir les combinaisons de fonctionnalités avec CameraX 1.5

Temps de lecture : 6 min
Tahsin Masrur
Ingénieur logiciel

Les applications d'appareil photo modernes sont définies par des fonctionnalités puissantes et qui se chevauchent. Les utilisateurs s'attendent à enregistrer des vidéos avec une qualité HDR exceptionnelle, à capturer des mouvements fluides à 60 FPS et à obtenir des séquences d'une fluidité incroyable grâce à la stabilisation de l'aperçu, souvent en même temps.

En tant que développeurs, nous savons que la réalité est plus complexe. Comment garantir qu'un appareil spécifique est réellement compatible avec une combinaison donnée ? Jusqu'à présent, l'activation de plusieurs fonctionnalités était souvent un pari. Vous pouviez vérifier la compatibilité de chaque fonctionnalité, mais leur combinaison pouvait entraîner un comportement indéfini ou, pire encore, une session d'appareil photo échouée. Cette incertitude oblige les développeurs à être prudents, ce qui empêche les utilisateurs d'appareils compatibles de profiter de la meilleure expérience possible.

Par exemple, très peu d'appareils haut de gamme sont compatibles avec la vidéo HDR et 60 FPS simultanément. Par conséquent, la plupart des applications évitent d'activer les deux en même temps pour éviter une mauvaise expérience utilisateur sur la majorité des téléphones.

Pour résoudre ce problème, nous introduisons Feature Group dans CameraX, une nouvelle API conçue pour éliminer ces incertitudes. Vous pouvez désormais vérifier si une combinaison spécifique de fonctionnalités est compatible avant de configurer l'appareil photo, ou simplement indiquer vos priorités à CameraX et le laisser activer la combinaison la mieux prise en charge pour vous.

Pour les nouveaux utilisateurs de CameraX

Avant de nous pencher sur la nouvelle API Feature Group, rappelons rapidement ce qu'est CameraX. CameraX est une bibliothèque d'assistance Jetpack conçue pour vous aider à développer plus facilement des applications d'appareil photo. Elle fournit une surface d'API cohérente et facile à utiliser qui fonctionne sur la plupart des appareils Android, avec une rétrocompatibilité avec Android 6.0 (niveau d'API 23). Si vous ne connaissez pas CameraX, nous vous recommandons de consulter la documentation officielle et d'essayer l’atelier de programmation pour commencer.

Ce que vous pouvez créer avec l'API Feature Group

Vous n'avez plus besoin de parier sur les combinaisons de fonctionnalités et pouvez offrir en toute confiance les meilleures expériences d'appareil photo possibles, comme la vidéo HDR et 60 FPS simultanées sur du matériel compatible (par exemple, un Pixel 10 Pro), tout en évitant les erreurs sur les appareils qui ne sont pas compatibles avec la combinaison.

unnamed.png

Pixel 10 Pro activant à la fois le HDR et 60 FPS simultanément

unnamed (1).png

Sur un appareil plus ancien où le HDR et 60 FPS ne peuvent pas s'exécuter simultanément, seul le HDR est activé, tandis que l'option 60 FPS est désactivée.

Avec l'API Feature Group, vous pouvez :

  • Créer des interfaces utilisateur dynamiques et plus intelligentes : activez ou désactivez intelligemment les paramètres de votre interface utilisateur en fonction de la compatibilité matérielle en temps réel. Par exemple, si un utilisateur active le HDR, vous pouvez immédiatement griser et désactiver l'option 60 FPS si la combinaison n'est pas compatible sur cet appareil. 
unsupported-features-disabled.gif
  • Offrir un mode "Haute qualité" fiable  : configurez l'appareil photo avec une liste priorisée des fonctionnalités souhaitées. CameraX recherche et active automatiquement la combinaison la mieux prise en charge pour n'importe quel appareil, ce qui garantit un excellent résultat sans logique complexe et spécifique à l'appareil.
  • Éviter les échecs de session de l'appareil photo : en vérifiant la compatibilité à l'avance, vous empêchez l'appareil photo de tenter de configurer une combinaison non compatible, ce qui élimine une source courante de plantages et offre une expérience utilisateur fluide.

Fonctionnement : les composants principaux

La nouvelle API est axée sur les principaux ajouts à SessionConfig et CameraInfo.

  1. GroupableFeature : cette API introduit un ensemble de fonctionnalités groupables prédéfinies, telles que HDR_HLG10, FPS_60, PREVIEW_STABILIZATION et IMAGE_ULTRA_HDR. En raison de limitations de calcul, seul un ensemble spécifique de fonctionnalités peut être regroupé avec le haut degré de fiabilité fourni par cette API. Nous nous efforçons d'étendre cette liste et d'ajouter la compatibilité avec d'autres fonctionnalités dans les prochaines versions.
  2. Nouveaux paramètres SessionConfig : cette classe, utilisée pour démarrer une session d'appareil photo, accepte désormais deux nouveaux paramètres :
    • requiredFeatureGroup : utilisez-le pour les fonctionnalités qui doivent être compatibles pour que la configuration réussisse. Il est idéal pour les fonctionnalités qu'un utilisateur active explicitement, comme l'activation/la désactivation d'un commutateur "HDR". Pour garantir une expérience déterministe et cohérente, l'appel bindToLifecycle génère une IllegalArgumentException si la combinaison demandée n'est pas compatible, au lieu d'ignorer silencieusement une demande de fonctionnalité. L'API CameraInfo#isFeatureGroupSupported (voir les détails ci-dessous) doit être utilisée pour interroger ce résultat au préalable.
    • preferredFeatureGroup : utilisez-le pour les fonctionnalités souhaitables, mais facultatives, par exemple lorsque vous souhaitez implémenter un mode "Haute qualité" par défaut. Vous fournissez une liste des fonctionnalités souhaitées classées par ordre de priorité, et CameraX active automatiquement la combinaison la plus prioritaire compatible avec l'appareil.
  3. CameraInfo#isFeatureGroupSupported() : il s'agit de la méthode de requête principale pour vérifier explicitement si un groupe de fonctionnalités est compatible. Elle est idéale pour ne fournir que les options de fonctionnalités compatibles aux utilisateurs dans l'interface utilisateur de votre application. Vous lui transmettez un SessionConfig, et il renvoie une valeur booléenne indiquant si la combinaison est compatible. Si vous avez l'intention de lier un SessionConfig avec des fonctionnalités requises, vous devez d'abord utiliser cette API pour vous assurer qu'elle est compatible. 

Implémentation en pratique

Voyons comment utiliser ces composants pour améliorer l'expérience de l'appareil photo.

Scénario 1 : Mode "Haute qualité" au mieux de ses capacités

Si vous souhaitez activer les meilleures fonctionnalités possibles par défaut, vous pouvez fournir une liste priorisée à preferredFeatureGroup. Dans cet exemple, nous indiquons à CameraX de donner la priorité au HDR, puis à 60 FPS et enfin à la stabilisation de l'aperçu. CameraX gère la complexité de la vérification de toutes les combinaisons possibles et du choix de la meilleure compatible avec l'appareil.

Par exemple, si un appareil peut gérer le HDR et 60 FPS ensemble, mais pas avec la stabilisation de l'aperçu, CameraX activera les deux premiers et ignorera le troisième. De cette façon, vous obtenez la meilleure expérience possible sans écrire de vérifications complexes et spécifiques à l'appareil.

cameraProvider.bindToLifecycle(

    lifecycleOwner,

    cameraSelector,

    SessionConfig(

        useCases = listOf(preview, videoCapture),

        // The order of features in this list determines their priority. 

        // CameraX will enable the best-supported combination based on these

        // priorities: HDR_HLG10 > FPS_60 > Preview Stabilization.  

        preferredFeatureGroup =

           listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),

    ).apply {

        // (Optional) Get a callback with the enabled features

        // to update your UI. 

        setFeatureSelectionListener { selectedFeatures ->

            updateUiIndicators(selectedFeatures)

        }

    }

)

Pour cet extrait de code, CameraX tentera d'activer les combinaisons de fonctionnalités dans l'ordre de priorité suivant, en sélectionnant la première entièrement compatible avec l'appareil :

  1. HDR + 60 FPS + Stabilisation de l'aperçu
  2. HDR + 60 FPS
  3. HDR + Stabilisation de l'aperçu
  4. HDR
  5. 60 FPS + Stabilisation de l'aperçu
  6. 60 FPS
  7. Stabilisation de l'aperçu
  8. Aucune des fonctionnalités ci-dessus

Scénario 2 : Créer une interface utilisateur réactive

Pour créer une interface utilisateur qui répond aux sélections de l'utilisateur et l'empêche de sélectionner une combinaison de fonctionnalités non compatible, vous pouvez interroger directement la compatibilité. La fonction ci-dessous vérifie les fonctionnalités incompatibles avec les sélections actuelles de l'utilisateur, ce qui vous permet de désactiver les éléments d'interface utilisateur correspondants.

/**

 * Returns a list of features that are NOT supported in combination

 * with the currently selected features.

 */

fun getUnsupportedFeatures(

    currentFeatures: Set<GroupableFeature>

): Set<GroupableFeature> {

    val unsupportedFeatures = mutableSetOf<GroupableFeature>()

    val appFeatureOptions = setOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION)


    // Iterate over every available feature option in your app. 

    appFeatureOptions.forEach { featureOption ->

        // Skip features the user has already selected. 

        if (currentFeatures.contains(featureOption)) return@forEach


        // Check if adding this new feature is supported. 

        val isSupported = cameraInfo.isFeatureGroupSupported(

            SessionConfig(

                useCases = useCases,

                // Check the new feature on top of existing ones.

                requiredFeatureGroup = currentFeatures + featureOption

            )

        )


        if (!isSupported) {

            unsupportedFeatures.add(featureOption)

        }

    }


    return unsupportedFeatures

}

Vous pouvez ensuite intégrer cette logique dans votre ViewModel ou votre contrôleur d'interface utilisateur pour réagir aux entrées de l'utilisateur et relier l'appareil photo avec une configuration garantie.

// Invoked when user turns some feature on/off.

fun onFeatureChange(currentFeatures: Set<GroupableFeature>) {

    // Identify features that are unsupported with the current selection.

    val unsupportedFeatures = getUnsupportedFeatures(currentFeatures)



    // Update app UI so that users can't enable them.

    updateDisabledFeatures(unsupportedFeatures)



    // Since the UI now only allows selecting supported feature combinations, 

    // `currentFeatures` is always valid. This allows setting

    // `requiredFeatureGroup` directly, without needing to re-check for

    // support or set a feature selection listener.  

    cameraProvider.bindToLifecycle(

        lifecycleOwner,

        cameraSelector,

        SessionConfig(

            useCases = listOf(preview, videoCapture),

            requiredFeatureGroup = currentFeatures,

        )

    )

}

Pour voir ces concepts dans une application fonctionnelle, vous pouvez explorer notre application de test interne. Elle fournit une implémentation complète des scénarios "au mieux de ses capacités" et "interface utilisateur réactive" décrits ci-dessus.

Remarque : Il s'agit d'une application de test et non d'un exemple officiellement compatible. Bien qu'il s'agisse d'une excellente référence pour l'API Feature Group, elle n'a pas été optimisée pour une utilisation en production.

Lancez-vous dès maintenant

L'API Feature Group élimine l'ambiguïté liée à l'utilisation de fonctionnalités avancées de l'appareil photo. En fournissant un moyen déterministe d'interroger la compatibilité des fonctionnalités, vous pouvez créer des applications d'appareil photo plus puissantes et fiables en toute confiance.

L'API est disponible en version expérimentale dans CameraX 1.5 et devrait devenir entièrement stable dans la version 1.6, avec davantage de compatibilité et d'améliorations à venir.

Pour en savoir plus, consultez la documentation officielle. Nous avons hâte de découvrir vos créations et de recevoir vos commentaires. Veuillez nous faire part de vos impressions et signaler les problèmes par l'un des moyens suivants :

Lire la suite