Notícias sobre produtos

Conheça o CameraX 1.5: gravação de vídeo avançada e captura de imagens de nível profissional

Leitura de 7 min
Ver o perfil de Scott Nien
Scott Nien Engenheiro de software

A equipe do CameraX tem o prazer de anunciar o lançamento da versão 1.5. A atualização mais recente foca em trazer recursos de nível profissional para você e facilitar a configuração da sessão de câmera.

Para gravação de vídeo, os usuários agora podem capturar vídeos incríveis em câmera lenta ou com alta taxa de quadros sem esforço. Além disso, a nova API Feature Group permite ativar com confiança combinações complexas, como HDR de 10 bits e 60 QPS, garantindo resultados consistentes em todos os 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 você pode aproveitar a saída Ultra HDR mesmo ao usar as poderosas extensões de câmera.

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 incríveis.

Gravação de vídeo avançada: combinações de alta velocidade e 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 frame rate alto

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

A implementação é simples se você conhece a API VideoCapture.

1. Verificar se há suporte para alta velocidade:use o novo método Recorder.getHighSpeedVideoCapabilities() para consultar se o dispositivo é compatível com 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 do vídeo compatíveis) para criar um HighSpeedVideoSessionConfig. Em seguida, consulte os intervalos de frame rate aceitos 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 para o usuário. No momento, esse recurso é compatível com as câmeras traseiras de quase todos os dispositivos Pixel e alguns modelos de outros fabricantes.

Confira mais detalhes na postagem do blog (em inglês).

Combine atributos com confiança: a API Feature Group

O CameraX 1.5 apresenta a API Feature Group (em inglês), que elimina a necessidade de adivinhar a compatibilidade de recursos. Com base na API de consulta de combinação de recursos do Android 15, agora é possível ativar vários recursos juntos com confiança, garantindo uma sessão de câmera estável. No momento, o grupo de recursos é compatível com: HDR (HLG), 60 qps, estabilização de prévia e Ultra HDR. Por exemplo, é possível ativar o HDR, 60 QPS e a estabilização de prévia simultaneamente nas séries Pixel 10 e Galaxy S25. As próximas melhorias vão incluir gravação em 4K e zoom ultra-wide. 

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. A 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, a CameraX tenta ativar os recursos nesta ordem:

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

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

Agora você pode 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 na imagem abaixo. 

unsupported-features-disabled.gif

Para determinar se é necessário esmaecer uma alternância, use os códigos a seguir para verificar a compatibilidade com a combinação de recursos. Primeiro, consulte o status de cada recurso individual. Depois que um recurso é ativado, consulte novamente os recursos restantes com os 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 sobre o grupo de recursos para mais informações. 

Mais melhorias de vídeo

  • Melhorias na câmera simultânea:com a CameraX 1.5.1, agora é possível vincular casos de uso de visualização, captura de imagem e captura de vídeo simultaneamente para cada SingleCameraConfig no modo não de composição. Além disso, no modo escrever (mesmos casos de uso com CompositionSettings),  agora é possível definir o CameraEffect que é aplicado ao resultado final da composição.
  • Ativação dinâmica do som:agora é possível iniciar uma gravação com o som 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:agora o CameraX envia o erro VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE de maneira confiável, permitindo que seu app lide com situações de pouco armazenamento e informe o usuário.
  • Otimização com pouca luz:em dispositivos compatíveis (como a série Pixel 10), é possível ativar CameraControl.enableLowLightBoostAsync para aumentar automaticamente o brilho da prévia e dos fluxos de vídeo em ambientes escuros.

Captura de imagens de nível profissional

O CameraX 1.5 traz grandes upgrades para o ImageCapture (link em inglês) para desenvolvedores que exigem máxima qualidade e flexibilidade.

Use o controle criativo com a captura DNG (RAW)

Para 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 gradação de cores de nível profissional. A API é compatível com a captura do arquivo DNG sozinho ou com a 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 incrível fotografia computacional das extensões de câmera (como o modo noturno) combinada com a cor brilhante e o alcance dinâmico do Ultra HDR. Esse recurso agora está disponível em 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()

Melhorias na API principal e na 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. Chega de chamadas manuais de unbind():as APIs CameraX têm reconhecimento de ciclo de vida. Ele vai "desvincular" implicitamente seus casos de uso quando a atividade ou outro LifecycleOwner for destruído. No entanto, para atualizar casos de uso ou trocar de câmera, ainda é necessário chamar unbind() ou unbindAll() antes de vincular novamente. Agora, com a CameraX 1.5, ao vincular uma nova SessionConfig, a CameraX atualiza a sessão sem problemas, eliminando a necessidade de chamadas de desvinculação.
  2. Controle determinístico de frame rate:a nova API SessionConfig apresenta uma maneira determinística de gerenciar o frame rate. Ao contrário do setTargetFrameRate anterior, que era apenas uma dica, esse novo método garante que o intervalo de frame rate especificado será aplicado após a configuração. Para garantir a precisão, consulte as taxas de frames compatíveis usando CameraInfo.getSupportedFrameRateRanges(SessionConfig). Ao transmitir o SessionConfig completo, o CameraX pode determinar com precisão os intervalos compatíveis com base nas configurações de fluxo.

A Camera-Compose agora é estável

Sabemos o quanto você gosta do Jetpack Compose e temos o prazer de anunciar que a biblioteca camera-compose agora está estável na versão 1.5.1! Esta 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 extensão da prévia. Vamos continuar adicionando mais recursos ao camera-compose em versões futuras.

Melhorias em ImageAnalysis e CameraControl

  • Ajuste da intensidade da lanterna:tenha controle refinado sobre a lanterna do dispositivo com novas APIs. É possível consultar a intensidade máxima compatível 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 de ImageAnalysis, simplificando a integração com outras bibliotecas e APIs. Isso é ativado ao invocar ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).

Comece a usar hoje mesmo

Atualize suas dependências para a CameraX 1.5 hoje mesmo e confira os novos recursos incríveis. Aguardamos sua participação!

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 de câmera simultâneas. 

[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 estas 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 para desenvolvedores do CameraX ou envie um relatório do bug:

Escrito por:
Continuar lendo