Actualités des produits

Présentation de CameraX 1.5 : enregistrement vidéo puissant et capture d'images de niveau professionnel

Temps de lecture : 7 min
Scott Nien
Ingénieur logiciel

L'équipe CameraX est ravie d'annoncer la sortie de la version 1.5 ! Cette dernière mise à jour vous permet d'accéder à des fonctionnalités professionnelles et de configurer la session de caméras plus facilement que jamais.

Pour l'enregistrement vidéo, les utilisateurs peuvent désormais capturer sans effort de superbes vidéos au ralenti ou à fréquence d'images élevée. Plus important encore, la nouvelle API Feature Group vous permet d'activer en toute confiance des combinaisons complexes telles que HDR 10 bits et 60 FPS, ce qui garantit des résultats cohérents sur les appareils compatibles.

En ce qui concerne la capture d'images, vous bénéficiez d'une flexibilité maximale grâce à la prise en charge de la capture de fichiers DNG (RAW) non traités et non compressés. De plus, vous pouvez désormais profiter de la sortie Ultra HDR même lorsque vous utilisez des extensions d'appareil photo puissantes.

Ces fonctionnalités reposent sur la nouvelle API SessionConfig, qui simplifie la configuration et la reconfiguration des caméras. Découvrons maintenant ces nouvelles fonctionnalités intéressantes.

Enregistrement vidéo puissant : haute vitesse et combinaisons de fonctionnalités

CameraX 1.5 étend considérablement ses fonctionnalités vidéo, ce qui permet de créer des expériences d'enregistrement plus créatives et robustes.

Vidéo au ralenti et à fréquence d'images élevée

La vidéo au ralenti, l'une de nos fonctionnalités les plus attendues, est désormais disponible. Vous pouvez désormais capturer des vidéos à haute vitesse (par exemple, 120 ou 240 FPS) et les encoder directement en un ralenti spectaculaire. Vous pouvez également enregistrer à la même fréquence d'images élevée pour obtenir une vidéo exceptionnellement fluide.

L'implémentation est simple si vous connaissez l'API VideoCapture.

1. Vérifiez la prise en charge de la haute vitesse : utilisez la nouvelle méthode Recorder.getHighSpeedVideoCapabilities() pour vérifier si l'appareil prend en charge cette fonctionnalité.

val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

if (highSpeedCapabilities == null) {
    // This camera device does not support high-speed video.
    return
}

2. Configurer et associer le cas d'utilisation : utilisez le videoCapabilities renvoyé (qui contient des informations sur la qualité vidéo compatible) pour créer une HighSpeedVideoSessionConfig. Vous devez ensuite interroger les plages de fréquences d'images compatibles via cameraInfo.getSupportedFrameRateRanges() et définir la plage souhaitée. Appelez setSlowMotionEnabled(true) pour enregistrer des vidéos au ralenti. Sinon, des vidéos à fréquence d'images élevée seront enregistrées. La dernière étape consiste à utiliser le Recorder.prepareRecording().start() habituel pour commencer à enregistrer la vidéo.

val preview = Preview.Builder().build()
val quality = highSpeedCapabilities
        .getSupportedQualities(DynamicRange.SDR).first()

val recorder = Recorder.Builder()
      .setQualitySelector(QualitySelector.from(quality)))
      .build()

val videoCapture = VideoCapture.withOutput(recorder)

val frameRateRange = cameraInfo.getSupportedFrameRateRanges(      
       HighSpeedVideoSessionConfig(videoCapture, preview)
).first()

val sessionConfig = HighSpeedVideoSessionConfig(
    videoCapture, 
    preview, 
    frameRateRange = frameRateRange, 
    // Set true for slow-motion playback, or false for high-frame-rate
    isSlowMotionEnabled = true
)

cameraProvider.bindToLifecycle(
     lifecycleOwner, cameraSelector, sessionConfig)

// Start recording slow motion videos. 
val recording = recorder.prepareRecording(context, outputOption)
      .start(executor, {})

Compatibilité et limites

L'enregistrement à haute vitesse nécessite la prise en charge spécifique de CameraConstrainedHighSpeedCaptureSession et CamcorderProfile. Effectuez toujours la vérification des fonctionnalités et n'activez l'enregistrement à haute vitesse que sur les appareils compatibles pour éviter une mauvaise expérience utilisateur. Cette fonctionnalité est actuellement disponible sur les caméras arrière de presque tous les appareils Pixel et sur certains modèles d'autres fabricants.

Pour en savoir plus, consultez cet article de blog.

Combiner des caractéristiques avec assurance : l'API Feature Group

CameraX 1.5 introduit l'API Feature Group, qui élimine les incertitudes concernant la compatibilité des fonctionnalités. Grâce à l'API de requête de combinaison de fonctionnalités d'Android 15, vous pouvez désormais activer plusieurs fonctionnalités ensemble en toute confiance, ce qui garantit une session de caméra stable. Le groupe de fonctionnalités est actuellement compatible avec les éléments suivants : HDR (HLG), 60 FPS, stabilisation de l'aperçu et Ultra HDR. Par exemple, vous pouvez activer simultanément le HDR, 60 FPS et la stabilisation de l'aperçu sur les appareils des gammes Pixel 10 et Galaxy S25. Nous prévoyons d'ajouter l'enregistrement en 4K et le zoom ultra grand-angle. 

L'API Feature Group permet deux cas d'utilisation essentiels :

Cas d'utilisation 1 : Prioriser la meilleure qualité

Si vous souhaitez effectuer une capture en utilisant la meilleure combinaison possible de fonctionnalités, vous pouvez fournir une liste classée par ordre de priorité. CameraX tentera de les activer dans l'ordre, en sélectionnant la première combinaison entièrement compatible avec l'appareil.

val sessionConfig = SessionConfig(
    useCases = listOf(preview, videoCapture),
    preferredFeatureGroup = listOf(
        GroupableFeature.HDR_HLG10,
        GroupableFeature.FPS_60,
        GroupableFeature.PREVIEW_STABILIZATION
    )
).apply {
    // (Optional) Get a callback with the enabled features to update your UI.
    setFeatureSelectionListener { selectedFeatures ->
        updateUiIndicators(selectedFeatures)
    }
}
processCameraProvider.bindToLifecycle(activity, cameraSelector, sessionConfig)

Dans cet exemple, CameraX tente d'activer les fonctionnalités dans l'ordre suivant :

  1. HDR + 60 FPS + Stabilisation de l'aperçu
  2. HDR + 60 FPS
  3. HDR+ et 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. Aucun

Cas d'utilisation 2 : Créer une UI de paramètres destinée aux utilisateurs

Vous pouvez désormais indiquer précisément les combinaisons de fonctionnalités compatibles dans l'UI des paramètres de votre application, en désactivant les boutons bascule pour les options non compatibles, comme dans l'image ci-dessous. 

unsupported-features-disabled.gif

Pour déterminer si un bouton bascule doit être grisé, utilisez les codes suivants pour vérifier la compatibilité de la combinaison de fonctionnalités. Commencez par interroger l'état de chaque fonctionnalité. Une fois qu'une fonctionnalité est activée, interrogez à nouveau les fonctionnalités restantes avec les fonctionnalités activées pour voir si leurs boutons bascule doivent maintenant être grisés en raison de contraintes de compatibilité.

fun disableFeatureIfNotSuported(
   enabledFeatures: Set<GroupableFeature>,     
   featureToCheck:GroupableFeature
) {
 val sessionConfig = SessionConfig(
     useCases = useCases,
     requiredFeatureGroup = enabledFeatures + featureToCheck
 )
 val isSupported = cameraInfo.isFeatureGroupSupported(sessionConfig)

 if (!isSupported) {
     // disable the toggle for featureToCheck
 }
}

Pour en savoir plus, consultez l'article de blog sur les groupes de fonctionnalités

Plus d'améliorations vidéo

  • Améliorations apportées à la caméra simultanée : avec CameraX 1.5.1, vous pouvez désormais lier simultanément les cas d'utilisation Preview, ImageCapture et VideoCapture pour chaque SingleCameraConfig en mode sans composition. De plus, en mode Composition (mêmes cas d'utilisation avec CompositionSettings),  vous pouvez désormais définir le CameraEffect appliqué au résultat final de la composition.
  • Coupure du son dynamique : vous pouvez désormais démarrer un enregistrement en coupant le son à l'aide de PendingRecording.withAudioEnabled(boolean initialMuted) et permettre à l'utilisateur de réactiver le son ultérieurement à l'aide de Recording.mute(boolean muted).
  • Gestion améliorée de l'espace de stockage insuffisant : CameraX envoie désormais l'erreur VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE de manière fiable, ce qui permet à votre application de gérer correctement les situations de stockage insuffisant et d'en informer l'utilisateur.
  • Low Light Boost : sur les appareils compatibles (comme la gamme Pixel 10), vous pouvez activer CameraControl.enableLowLightBoostAsync pour éclaircir automatiquement l'aperçu et les flux vidéo dans les environnements sombres.

Capture d'images de qualité professionnelle

CameraX 1.5 apporte des améliorations majeures à ImageCapture pour les développeurs qui exigent une qualité et une flexibilité maximales.

Contrôlez votre créativité avec la capture DNG (RAW)

Pour un contrôle complet du post-traitement, CameraX est désormais compatible avec la capture DNG (RAW). Vous avez ainsi accès aux données brutes et non compressées des images directement depuis le capteur de la caméra, ce qui vous permet de les retoucher et d'étalonner les couleurs comme un professionnel. L'API permet de capturer le fichier DNG seul ou de capturer simultanément les sorties JPEG et DNG. Consultez l'exemple de code ci-dessous pour savoir comment capturer simultanément des fichiers JPEG et DNG.

val capabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
    if (capabilities.supportedOutputFormats
             .contains(OUTPUT_FORMAT_RAW_JPEG)) {
        // Capture both RAW and JPEG formats.
        setOutputFormat(OUTPUT_FORMAT_RAW_JPEG)
    }
}.build()
// ... bind imageCapture to lifecycle ...


// Provide separate output options for each format.
val outputOptionRaw = /* ... configure for image/x-adobe-dng ... */
val outputOptionJpeg = /* ... configure for image/jpeg ... */
imageCapture.takePicture(
    outputOptionRaw,
    outputOptionJpeg,
    executor,
    object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(results: OutputFileResults) {
            // This callback is invoked twice: once for the RAW file
            // and once for the JPEG file.
        }

        override fun onError(exception: ImageCaptureException) {}
    }
)

Ultra HDR pour les extensions d'appareil photo

Profitez du meilleur des deux mondes : la photographie computationnelle époustouflante des extensions d'appareil photo (comme le mode Nuit) combinée aux couleurs éclatantes et à la plage dynamique de l'Ultra HDR. Cette fonctionnalité est désormais disponible sur de nombreux téléphones Android haut de gamme récents, comme les gammes Pixel 9/10 et Samsung S24/S25.

// Support UltraHDR when Extension is enabled. 

val extensionsEnabledCameraSelector = extensionsManager
     .getExtensionEnabledCameraSelector(
        CameraSelector.DEFAULT_BACK_CAMERA, ExtensionMode.NIGHT)

val imageCapabilities = ImageCapture.getImageCaptureCapabilities(
               cameraProvider.getCameraInfo(extensionsEnabledCameraSelector)

val imageCapture = ImageCapture.Builder()
     .apply {
       if (imageCapabilities.supportedOutputFormats
                .contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR) {
           setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)

       }

     }.build()

Améliorations de l'API principale et de l'usabilité

Une nouvelle façon de configurer : SessionConfig

Comme le montrent les exemples ci-dessus, SessionConfig est un nouveau concept dans CameraX 1.5. Elle centralise la configuration et simplifie l'API de deux manières principales :

  1. Plus d'appels unbind() manuels : les API CameraX sont compatibles avec le cycle de vie. Il "dissociera" implicitement vos cas d'utilisation lorsque l'activité ou un autre LifecycleOwner sera détruit. Toutefois, pour mettre à jour les cas d'utilisation ou changer de caméra, vous devez toujours appeler unbind() ou unbindAll() avant de relier. Désormais, avec CameraX 1.5, lorsque vous liez un nouveau SessionConfig, CameraX met à jour la session de manière fluide pour vous, ce qui élimine la nécessité d'appels de dissociation.
  2. Contrôle déterministe de la fréquence d'images : la nouvelle API SessionConfig introduit une méthode déterministe pour gérer la fréquence d'images. Contrairement à l'ancien setTargetFrameRate, qui n'était qu'une indication, cette nouvelle méthode garantit que la plage de fréquences d'images spécifiée sera appliquée si la configuration est réussie. Pour garantir la précision, vous devez interroger les fréquences d'images compatibles à l'aide de CameraInfo.getSupportedFrameRateRanges(SessionConfig). En transmettant le SessionConfig complet, CameraX peut déterminer précisément les plages compatibles en fonction des configurations de flux.

Camera-Compose est désormais stable

Nous savons à quel point vous appréciez Jetpack Compose. Nous avons donc le plaisir de vous annoncer que la bibliothèque camera-compose est désormais stable dans la version 1.5.1 ! Cette version inclut des corrections de bugs critiques liés à l'utilisation de CameraXViewfinder avec des fonctionnalités Compose telles que moveableContentOf et Pager, ainsi que la résolution d'un problème d'étirement de l'aperçu. Nous continuerons d'ajouter des fonctionnalités à camera-compose dans les prochaines versions.

Améliorations apportées à ImageAnalysis et CameraControl

  • Réglage de l'intensité de la lampe torche : contrôlez précisément la lampe torche de l'appareil grâce aux nouvelles API. Vous pouvez interroger l'intensité maximale acceptée à l'aide de CameraInfo.getMaxTorchStrengthLevel(), puis définir le niveau souhaité avec CameraControl.setTorchStrengthLevel().
  • Compatibilité NV21 dans ImageAnalysis : vous pouvez désormais demander le format d'image NV21 directement à partir de ImageAnalysis, ce qui simplifie l'intégration avec d'autres bibliothèques et API. Pour l'activer, appelez ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).

Lancez-vous dès maintenant

Mettez à jour vos dépendances vers CameraX 1.5 dès aujourd'hui et découvrez les nouvelles fonctionnalités intéressantes. Nous avons hâte de découvrir vos créations.

Pour utiliser CameraX 1.5,  veuillez ajouter les dépendances suivantes à votre fichier libs.versions.toml. (Nous vous recommandons d'utiliser la version 1.5.1, qui contient de nombreux correctifs de bugs critiques et des améliorations pour les caméras simultanées.) 

[versions]

camerax = "1.5.1"


[libraries]

..

androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }

androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }

androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }

androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }

androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }

androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" }

Ajoutez ensuite ces éléments aux dépendances build.gradle.kts de votre module :

dependencies {

  ..

  implementation(libs.androidx.camera.core)
  implementation(libs.androidx.camera.lifecycle)

  implementation(libs.androidx.camera.camera2)

  implementation(libs.androidx.camera.view) // for PreviewView 
  implementation(libs.androidx.camera.compose) // for compose UI

  implementation(libs.androidx.camera.extensions) // For Extensions 

}

Vous avez des questions ou vous souhaitez contacter l'équipe CameraX ? Rejoignez le groupe de discussion des développeurs CameraX ou remplissez un rapport de bug :

Écrit par :

Lire la suite