Notícias sobre produtos

Apresentamos o CameraX 1.5: gravação de vídeo avançada e captura de imagem profissional

Leitura de 7 minutos
Scott Nien
Engenheiro de software

A equipe do CameraX tem o prazer de anunciar o lançamento da versão 1.5. Essa atualização mais recente se concentra em oferecer recursos de nível profissional e facilitar a configuração da sessão da câmera.

Para gravação de vídeo, os usuários agora podem capturar vídeos em câmera lenta ou com alta taxa de frames sem dificuldade. Mais importante ainda, a nova API Feature Group permite ativar combinações complexas, como HDR de 10 bits e 60 QPS, garantindo resultados consistentes em dispositivos compatíveis.

Na captura de imagens , você tem flexibilidade máxima com suporte para capturar arquivos DNG (RAW) não processados e não compactados. Além disso, agora é possível aproveitar a saída Ultra HDR mesmo ao usar extensões de câmera avançadas.

Esses recursos são baseados na nova API SessionConfig, que simplifica a configuração e a reconfiguração da câmera. Agora, vamos conferir os detalhes desses novos recursos.

Gravação de vídeo avançada: alta velocidade e combinações de recursos

O CameraX 1.5 expande significativamente os recursos de vídeo, permitindo experiências de gravação mais criativas e robustas.

Vídeo em câmera lenta e com alta taxa de frames

Um dos nossos recursos mais aguardados, o vídeo em câmera lenta, já está disponível. Agora é possível capturar vídeos em alta velocidade (por exemplo, 120 ou 240 QPS) e codificá-los diretamente em um vídeo dramático em câmera lenta. Como alternativa, você pode gravar com a mesma alta taxa de frames para produzir vídeos excepcionalmente suaves.

A implementação é simples se você estiver familiarizado com a API VideoCapture.

1. Verifique o suporte de alta velocidade: use o novo Recorder.getHighSpeedVideoCapabilities() método para consultar se o dispositivo oferece suporte a esse recurso.

  val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

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

2. Configure e vincule o caso de uso: Use o videoCapabilities retornado (que contém informações de qualidade de vídeo com suporte) para criar um HighSpeedVideoSessionConfig. Em seguida, consulte os intervalos de taxa de frames com suporte usando cameraInfo.getSupportedFrameRateRanges() e defina o intervalo desejado. Invoque setSlowMotionEnabled(true) para gravar vídeos em câmera lenta. Caso contrário, ele vai gravar vídeos com alta taxa de frames. A etapa final é usar o Recorder.prepareRecording().start() normal para começar a gravar o vídeo.

  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, {})

Compatibilidade e limitações

A gravação em alta velocidade exige suporte específico para CameraConstrainedHighSpeedCaptureSession e CamcorderProfile. Sempre faça a verificação de capacidade e ative a gravação em alta velocidade apenas em dispositivos compatíveis para evitar uma experiência ruim do usuário. No momento, esse recurso é compatível com as câmeras traseiras de quase todos os dispositivos Pixel e modelos selecionados de outros fabricantes.

Confira a postagem do blog para mais detalhes.

Combine recursos com confiança: a API Feature Group

O CameraX 1.5 apresenta a API Feature Group, que elimina as dúvidas sobre a compatibilidade de recursos. Com base na API de consulta de combinação de recursos do Android 15 API, agora é possível ativar vários recursos juntos, garantindo uma sessão de câmera estável. O Feature Group oferece suporte a: HDR (HLG), 60 QPS, estabilização de visualização e Ultra HDR. Por exemplo, é possível ativar o HDR, 60 QPS e a estabilização de visualização simultaneamente nas séries Pixel 10 e Galaxy S25. Aprimoramentos futuros estão planejados para incluir gravação em 4K e zoom ultra-amplo. 

A API Feature Group permite dois casos de uso essenciais:

Caso de uso 1: priorizar a melhor qualidade

Se você quiser capturar usando a melhor combinação possível de recursos, forneça uma lista priorizada. O CameraX vai tentar ativá-los em ordem, selecionando a primeira combinação totalmente compatível com o dispositivo.

  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)

Neste exemplo, o CameraX tenta ativar os recursos nesta ordem:

  1. HDR + 60 QPS + estabilização de visualização
  2. HDR + 60 QPS
  3. HDR + estabilização de visualização
  4. HDR
  5. 60 QPS + estabilização de visualização
  6. 60 QPS
  7. Estabilização de visualização
  8. Nenhum

Caso de uso 2: criar uma interface de configurações voltada ao usuário

Agora é possível refletir com precisão quais combinações de recursos são compatíveis com a interface de configurações do app, desativando as opções não compatíveis, como a imagem abaixo. 

unsupported-features-disabled.gif

Para determinar se um botão precisa ser esmaecido, use os códigos a seguir para verificar o suporte à combinação de recursos. Inicialmente, consulte o status de cada recurso individual. Depois que um recurso é ativado, consulte novamente os recursos restantes com os recursos ativados para verificar se os botões precisam ser esmaecidos devido a restrições de compatibilidade.

  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
 }
}

Consulte a postagem do blog do Feature Group para mais informações. 

Mais aprimoramentos de vídeo

  • Melhorias simultâneas da câmera: com o CameraX 1.5.1, agora é possível vincular casos de uso de visualização + ImageCapture + VideoCapture simultaneamente para cada SingleCameraConfig no modo de não composição. Além disso, no modo de composição (os mesmos casos de uso com CompositionSettings),  agora é possível definir o CameraEffect que é aplicado ao resultado da composição final.
  • Desativação dinâmica:agora é possível iniciar uma gravação no estado desativado usando PendingRecording.withAudioEnabled(boolean initialMuted) e permitir que o usuário ative o som mais tarde usando Recording.mute(boolean muted).
  • Melhoria no tratamento de armazenamento insuficiente:o CameraX agora envia de forma confiável o erro VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE, permitindo que o app trate situações de pouco armazenamento e informe o usuário.
  • Aumento de luz baixa: em dispositivos compatíveis (como a série Pixel 10), é possível ativar CameraControl.enableLowLightBoostAsync para clarear automaticamente a visualização e os streams de vídeo em ambientes escuros.

Captura de imagem profissional

O CameraX 1.5 traz grandes upgrades para ImageCapture para desenvolvedores que exigem qualidade e flexibilidade máximas.

Liberte o controle criativo com a captura DNG (RAW)

Para ter controle total sobre o pós-processamento, o CameraX agora oferece suporte à captura DNG (RAW). Isso dá acesso aos dados de imagem não processados e não compactados diretamente do sensor da câmera, permitindo edição e classificação de cores de nível profissional. A API oferece suporte à captura do arquivo DNG sozinho ou à captura simultânea de saídas JPEG e DNG. Confira o exemplo de código abaixo para saber como capturar arquivos JPEG e DNG simultaneamente.

  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 extensões de câmera

Aproveite o melhor dos dois mundos: a fotografia computacional impressionante das extensões de câmera (como o modo noturno) combinada com a cor brilhante e o intervalo dinâmico do Ultra HDR. Esse recurso agora é compatível com muitos smartphones Android premium recentes, como as séries Pixel 9/10 e 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()

API principal e melhorias de usabilidade

Uma nova maneira de configurar: SessionConfig

Como visto nos exemplos acima, SessionConfig é um novo conceito no CameraX 1.5. Ele centraliza a configuração e simplifica a API de duas maneiras principais:

  1. Sem mais chamadas manuais unbind() Calls: as APIs do CameraX reconhecem o ciclo de vida. Ele vai "desvincular" implicitamente seus casos de uso quando a atividade ou outro LifecycleOwner for destruído. No entanto, atualizar casos de uso ou trocar de câmera ainda exige que você chame unbind() ou unbindAll() antes de revincular. Agora, com o CameraX 1.5, ao vincular um novo SessionConfig, o CameraX atualiza a sessão automaticamente, eliminando a necessidade de chamadas de desvinculação.
  2. Controle determinístico da taxa de quadros:a nova API SessionConfig apresenta uma maneira determinística de gerenciar a taxa de quadros. Ao contrário do setTargetFrameRate anterior, que era apenas uma dica, esse novo método garante que o intervalo de taxa de frames especificado seja aplicado após a configuração bem-sucedida. Para garantir a precisão, consulte as taxas de frames com suporte usando CameraInfo.getSupportedFrameRateRanges(SessionConfig). Ao transmitir o SessionConfig completo, o CameraX pode determinar com precisão os intervalos com suporte com base nas configurações de stream.

O Camera-Compose agora é estável

Sabemos o quanto você gosta do Jetpack Compose e temos o prazer de anunciar que a camera-compose biblioteca agora está estável na versão 1.5.1! Essa versão inclui correções de bugs críticos relacionados ao uso do CameraXViewfinder com recursos do Compose, como moveableContentOf e Pager, além de resolver um problema de alongamento da visualização. Vamos continuar adicionando mais recursos ao camera-compose em versões futuras.

Melhorias no ImageAnalysis e no CameraControl

  • Ajuste da intensidade da lanterna:tenha controle refinado sobre a lanterna do dispositivo com novas APIs. É possível consultar a intensidade máxima com suporte usando CameraInfo.getMaxTorchStrengthLevel() e definir o nível desejado com CameraControl.setTorchStrengthLevel().
  • Suporte a NV21 em ImageAnalysis: agora é possível solicitar o formato de imagem NV21 diretamente do ImageAnalysis, simplificando a integração com outras bibliotecas e APIs. Isso é ativado invocando ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).

Começar hoje mesmo

Atualize suas dependências para o CameraX 1.5 hoje mesmo e conheça os novos recursos. Estamos ansiosos para ver o que você vai criar.

Para usar o CameraX 1.5,  adicione as seguintes dependências ao libs.versions.toml. Recomendamos usar a versão 1.5.1, que contém muitas correções de bugs críticos e melhorias simultâneas da câmera.

  [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" }

Em seguida, adicione essas dependências ao build.gradle.kts do 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 

}

Tem dúvidas ou quer entrar em contato com a equipe do CameraX? Participe do grupo de discussão de desenvolvedores do CameraX ou envie um relatório de bug:

Escrito por:

Continuar lendo