Presentamos CameraX 1.5: Grabación de video potente y captura de imágenes de nivel profesional
Lectura de 7 min
El equipo de CameraX se complace en anunciar el lanzamiento de la versión 1.5. Esta actualización se enfoca en poner funciones de nivel profesional al alcance de tu mano y, al mismo tiempo, facilitar la configuración de la sesión de la cámara como nunca antes.
En cuanto a la grabación de videos, ahora los usuarios pueden capturar sin esfuerzo videos increíbles en cámara lenta o con una alta velocidad de fotogramas. Y lo que es más importante, la nueva API de Feature Group te permite habilitar con confianza combinaciones complejas, como HDR de 10 bits y 60 FPS, lo que garantiza resultados coherentes en todos los dispositivos compatibles.
En cuanto a la captura de imágenes, obtienes la máxima flexibilidad con la compatibilidad para capturar archivos DNG (RAW) sin procesar ni comprimir. Además, ahora puedes aprovechar la salida Ultra HDR incluso cuando usas las potentes extensiones de la cámara.
La base de estas funciones es la nueva API de SessionConfig, que optimiza la configuración y la reconfiguración de la cámara. Ahora, analicemos los detalles de estas nuevas y emocionantes funciones.
Grabación de video potente: Combinaciones de alta velocidad y funciones
CameraX 1.5 expande significativamente sus capacidades de video, lo que permite experiencias de grabación más creativas y sólidas.
Videos en cámara lenta y con velocidad de fotogramas alta
Ya está disponible una de nuestras funciones más esperadas: los videos en cámara lenta. Ahora puedes capturar videos de alta velocidad (p.ej., 120 o 240 fps) y codificarlos directamente en un video dramático en cámara lenta. Como alternativa, puedes grabar con la misma velocidad de fotogramas alta para producir videos excepcionalmente fluidos.
La implementación es sencilla si conoces la API de VideoCapture.
1. Verifica la compatibilidad con alta velocidad: Usa el nuevo método Recorder.getHighSpeedVideoCapabilities() para consultar si el dispositivo admite esta función.
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)
if (highSpeedCapabilities == null) {
// This camera device does not support high-speed video.
return
}2. Configura y vincula el caso de uso: Usa el videoCapabilities que se muestra (que contiene información sobre la calidad de video admitida) para compilar un HighSpeedVideoSessionConfig. Luego, debes consultar los rangos de velocidad de fotogramas admitidos a través de cameraInfo.getSupportedFrameRateRanges() y establecer el rango deseado. Invoca setSlowMotionEnabled(true) para grabar videos en cámara lenta; de lo contrario, se grabarán videos con una alta velocidad de fotogramas. El último paso es usar el Recorder.prepareRecording().start() normal para comenzar a grabar el video.
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, {})Compatibilidad y limitaciones
La grabación de alta velocidad requiere compatibilidad específica con CameraConstrainedHighSpeedCaptureSession y CamcorderProfile. Siempre realiza la verificación de capacidad y habilita la grabación de alta velocidad solo en los dispositivos compatibles para evitar una mala experiencia del usuario. Actualmente, esta función es compatible con las cámaras posteriores de casi todos los dispositivos Pixel y algunos modelos de otros fabricantes.
Consulta la entrada de blog para obtener más detalles.
Combina atributos con confianza: la API de Feature Group
CameraX 1.5 presenta la API de Feature Group, que elimina las conjeturas sobre la compatibilidad de las funciones. Según la API de consulta de combinación de funciones de Android 15, ahora puedes habilitar varias funciones juntas con confianza, lo que garantiza una sesión de cámara estable. Actualmente, el grupo de funciones admite HDR (HLG), 60 FPS, estabilización de vista previa y Ultra HDR. Por ejemplo, puedes habilitar HDR, 60 FPS y la estabilización de la vista previa de forma simultánea en las series Pixel 10 y Galaxy S25. Se planea incluir mejoras futuras, como la grabación en 4K y el zoom ultra gran angular.
La API de grupos de funciones habilita dos casos de uso esenciales:
Caso de uso 1: Priorizar la mejor calidad
Si deseas capturar con la mejor combinación posible de funciones, puedes proporcionar una lista priorizada. CameraX intentará habilitarlas en orden y seleccionará la primera combinación que el dispositivo admita por completo.
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)En este ejemplo, CameraX intenta habilitar las funciones en este orden:
- HDR + 60 FPS + Estabilización de vista previa
- HDR + 60 FPS
- HDR y estabilización de la vista previa
- HDR
- 60 FPS y estabilización de la vista previa
- 60 FPS
- Estabilización de versión preliminar
- Ninguno
Caso de uso 2: Compila una IU de configuración para el usuario
Ahora puedes reflejar con precisión qué combinaciones de funciones se admiten en la IU de configuración de tu app, inhabilitando los botones de activación para las opciones no admitidas, como se muestra en la siguiente imagen.
Para determinar si se debe inhabilitar un botón de activación, usa los siguientes códigos para verificar la compatibilidad con la combinación de funciones. Inicialmente, consulta el estado de cada función individual. Una vez que se habilita una función, vuelve a consultar las funciones restantes con las funciones habilitadas para ver si sus interruptores ahora deben estar inhabilitados debido a restricciones de compatibilidad.
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
}
}Consulta la entrada de blog sobre los grupos de funciones para obtener más información.
Más mejoras de video
- Mejoras en la cámara simultánea: Con CameraX 1.5.1, ahora puedes vincular los casos de uso de Preview, ImageCapture y VideoCapture de forma simultánea para cada SingleCameraConfig en el modo sin composición. Además, en el modo de redacción (los mismos casos de uso con CompositionSettings), ahora puedes establecer el
CameraEffectque se aplica al resultado final de la composición. - Silenciamiento dinámico: Ahora puedes iniciar una grabación en estado silenciado con
PendingRecording.withAudioEnabled(boolean initialMuted)y permitir que el usuario active el sonido más tarde conRecording.mute(boolean muted). - Mejoras en el manejo de almacenamiento insuficiente: Ahora, CameraX envía de forma confiable el error
VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE, lo que permite que tu app controle correctamente las situaciones de poco almacenamiento y se lo informe al usuario. - Mejorador con poca luz: En los dispositivos compatibles (como la serie Pixel 10), puedes habilitar CameraControl.enableLowLightBoostAsync para iluminar automáticamente las transmisiones de video y la vista previa en entornos oscuros.
Captura de imágenes de nivel profesional
CameraX 1.5 incluye actualizaciones importantes en ImageCapture para los desarrolladores que exigen la máxima calidad y flexibilidad.
Libera el control creativo con la captura en DNG (RAW)
Para tener un control total sobre el procesamiento posterior, CameraX ahora admite la captura en DNG (RAW). Esto te brinda acceso a los datos de imagen sin procesar ni comprimir directamente desde el sensor de la cámara, lo que permite realizar ediciones y correcciones de color de nivel profesional. La API admite la captura del archivo DNG solo o la captura simultánea de salidas JPEG y DNG. Consulta el siguiente código de muestra para ver cómo capturar archivos JPEG y DNG de forma simultánea.
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 para las extensiones de la cámara
Obtén lo mejor de ambos mundos: la impresionante fotografía computacional de las extensiones de la cámara (como el modo nocturno) combinada con el color brillante y el rango dinámico de Ultra HDR. Esta función ahora es compatible con muchos teléfonos Android premium recientes, como las series Pixel 9 y 10, y las series Samsung S24 y 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()Mejoras de la API principal y de usabilidad
Una nueva forma de configurar: SessionConfig
Como se ve en los ejemplos anteriores, SessionConfig es un concepto nuevo en CameraX 1.5. Centraliza la configuración y simplifica la API de dos maneras clave:
- No más llamadas manuales a
unbind(): Las APIs de CameraX están optimizadas para el ciclo de vida. De forma implícita, “desvinculará” tus casos de uso cuando se destruya la actividad o cualquier otroLifecycleOwner. Sin embargo, para actualizar los casos de uso o cambiar de cámara, debes llamar aunbind()ounbindAll()antes de volver a vincular. Ahora, con CameraX 1.5, cuando vinculas un nuevoSessionConfig, CameraX actualiza la sesión sin problemas, lo que elimina la necesidad de realizar llamadas de desvinculación. - Control determinístico de la velocidad de fotogramas: La nueva API de
SessionConfigpresenta una forma determinística de administrar la velocidad de fotogramas. A diferencia delsetTargetFrameRateanterior, que solo era una sugerencia, este nuevo método garantiza que se aplicará el rango de velocidad de fotogramas especificado después de una configuración correcta. Para garantizar la precisión, debes consultar las velocidades de fotogramas compatibles conCameraInfo.getSupportedFrameRateRanges(SessionConfig). Si pasas elSessionConfigcompleto, CameraX puede determinar con precisión los rangos admitidos según las configuraciones de transmisión.
Camera-Compose ahora es estable
Sabemos cuánto disfrutas de Jetpack Compose y nos complace anunciar que la biblioteca camera-compose ahora es estable en la versión 1.5.1. Esta versión incluye correcciones de errores críticos relacionados con el uso de CameraXViewfinder con funciones de Compose, como moveableContentOf y Pager, además de resolver un problema de estiramiento de la vista previa. Seguiremos agregando más funciones a camera-compose en las próximas versiones.
Mejoras en ImageAnalysis y CameraControl
- Ajuste de la intensidad de la linterna: Obtén un control detallado de la linterna del dispositivo con las nuevas APIs. Puedes consultar la intensidad máxima admitida con CameraInfo.getMaxTorchStrengthLevel() y, luego, establecer el nivel deseado con CameraControl.setTorchStrengthLevel().
- Compatibilidad con NV21 en
ImageAnalysis: Ahora puedes solicitar el formato de imagen NV21 directamente desdeImageAnalysis, lo que simplifica la integración con otras bibliotecas y APIs. Esto se habilita invocandoImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).
Comienza hoy mismo
Actualiza tus dependencias a CameraX 1.5 hoy mismo y explora las nuevas y emocionantes funciones. Ya queremos ver tus ideas en acción.
Para usar CameraX 1.5, agrega las siguientes dependencias a tu archivo libs.versions.toml. (Recomendamos usar la versión 1.5.1, que contiene muchas correcciones de errores críticos y mejoras de la cámara simultánea).
[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" }Luego, agrega lo siguiente a las dependencias de build.gradle.kts de tu módulo:
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
}¿Tienes preguntas o quieres comunicarte con el equipo de CameraX? Únete al grupo de discusión de desarrolladores de CameraX o envía un informe de errores:
-
Novedades de productosLas apps que se orienten a la próxima versión de Android ya no podrán escribir directamente en los contactos con el permiso WRITE_CONTACTS.
Roxanna Aliabadi Walker • Lectura de 6 min -
Novedades de productosA medida que se acelera el desarrollo basado en agentes, la ingeniería de Android alcanza una nueva y emocionante frontera: pasar de la finalización de código asistida a agentes que ejecutan tareas de extremo a extremo bajo tu dirección. Tienes total libertad y flexibilidad para elegir los modelos y agentes que usas.
Jason Buchel • Lectura de 3 min -
Novedades de productosHoy, compartimos cómo estamos llevando nuestra visión de “más que una tienda” al siguiente nivel. Desde la pestaña Tú, que ahora es la base personal de más de 250 millones de usuarios activos por mes, hasta nuestra plataforma de juegos unificada que conecta a más de 700 millones de perfiles de gamer, Google Play llega a los usuarios dondequiera que estén.
Paul Feng • Lectura de 3 min
Recibe la información más reciente sobre el desarrollo de Android en tu bandeja de entrada todas las semanas.