Notícias sobre produtos

Além dos recursos únicos: garantindo combinações de recursos com o CameraX 1.5

Leitura de 6 minutos
Tahsin Masrur
Engenheiro de software

Os apps de câmera modernos são definidos por recursos avançados e sobrepostos. Os usuários esperam gravar vídeos com HDR incrível, capturar movimentos fluidos a 60 QPS e ter imagens suaves com a estabilização de prévia, muitas vezes tudo ao mesmo tempo.

Como desenvolvedores, sabemos que a realidade é mais complicada. Como garantir que um dispositivo específico seja compatível com uma determinada combinação? Até agora, ativar vários recursos era uma aposta. Você pode verificar o suporte de recursos individuais, mas a combinação deles pode levar a um comportamento indefinido ou, pior, a uma sessão de câmera com falha.  Essa incerteza força os desenvolvedores a serem conservadores, o que impede que os usuários em dispositivos compatíveis tenham a melhor experiência possível.

Por exemplo, poucos dispositivos premium oferecem suporte confiável a HDR e vídeo de 60 QPS simultaneamente. Consequentemente, a maioria dos apps evita ativar os dois ao mesmo tempo para não prejudicar a experiência do usuário na maioria dos smartphones.

Para resolver isso, estamos lançando o Grupo de recursos no CameraX, uma nova API projetada para eliminar essa especulação. Agora é possível consultar se uma combinação específica de recursos é compatível antes de configurar a câmera ou simplesmente informar suas prioridades ao CameraX e deixar que ele ative a combinação mais compatível para você.

Para quem está começando a usar a CameraX

Antes de falarmos sobre a nova API Feature Group, vamos recapitular rapidamente o que é o CameraX. O CameraX é uma biblioteca de suporte do Jetpack criada para facilitar o desenvolvimento de apps de câmera. Ele fornece uma superfície de API consistente e fácil de usar que funciona na maioria dos dispositivos Android e é compatível com versões anteriores ao Android 6.0 (nível 23 da API). Se você não conhece o CameraX, recomendamos conferir a documentação oficial e testar o codelab para começar.

O que você pode criar com a API Feature Group

Você não precisa mais apostar em combinações de recursos e pode oferecer com confiança as melhores experiências de câmera possíveis, como HDR simultâneo e vídeo de 60 FPS em hardware compatível (por exemplo, um Pixel 10 Pro), evitando erros em dispositivos que não oferecem suporte à combinação.

unnamed.png

Pixel 10 Pro ativando HDR e 60 QPS simultaneamente

unnamed (1).png

Em um dispositivo mais antigo em que o HDR e 60 FPS não podem ser executados simultaneamente, apenas o HDR é ativado, enquanto a opção de 60 FPS é desativada.

Com a API Feature Group, você pode:

  • Crie UIs dinâmicas e mais inteligentes:ative ou desative configurações de maneira inteligente na sua UI com base no suporte de hardware em tempo real. Por exemplo, se um usuário ativar o HDR, você poderá desativar e esmaecer instantaneamente a opção de 60 FPS se a combinação não for compatível com o dispositivo. 
unsupported-features-disabled.gif
  • Ofereça um modo "Alta qualidade" confiável : configure a câmera com uma lista priorizada de recursos desejados. O CameraX encontra e ativa automaticamente a combinação mais compatível para qualquer dispositivo, garantindo um ótimo resultado sem lógica complexa e específica do dispositivo.
  • Evite falhas na sessão da câmera:ao verificar o suporte com antecedência, você evita que a câmera tente configurar uma combinação não compatível, eliminando uma fonte comum de falhas e oferecendo uma experiência do usuário tranquila.

Como funciona: os componentes principais

A nova API se concentra em adições importantes ao SessionConfig e ao CameraInfo.

  1. GroupableFeature: essa API apresenta um conjunto de recursos agrupáveis predefinidos, como HDR_HLG10, FPS_60, PREVIEW_STABILIZATION e IMAGE_ULTRA_HDR. Devido a limitações computacionais, apenas um conjunto específico de recursos pode ser agrupado com o alto grau de confiabilidade que essa API oferece. Estamos trabalhando para expandir essa lista e vamos oferecer suporte a mais recursos em versões futuras.
     
  2. Novos parâmetros SessionConfig: essa classe, usada para iniciar uma sessão de câmera, agora aceita dois novos parâmetros:
    • requiredFeatureGroup: use isso para recursos que precisam ser compatíveis para que a configuração seja bem-sucedida. É ideal para recursos que um usuário ativa explicitamente, como alternar uma chave "HDR". Para garantir uma experiência determinista e consistente, a chamada bindToLifecycle vai gerar um IllegalArgumentException se a combinação solicitada não for compatível, em vez de ignorar silenciosamente uma solicitação de recurso. A API CameraInfo#isFeatureGroupSupported (detalhes abaixo) deve ser usada para consultar esse resultado com antecedência.
    • preferredFeatureGroup: use isso para recursos desejáveis, mas opcionais, por exemplo, quando você quiser implementar um modo padrão "Alta qualidade". Você fornece uma lista dos recursos desejados ordenados de acordo com suas prioridades, e o CameraX ativa automaticamente a combinação de maior prioridade compatível com o dispositivo.
  3. CameraInfo#isFeatureGroupSupported(): esse é o método de consulta principal para verificar explicitamente se um grupo de recursos é compatível, sendo adequado para fornecer apenas opções de recursos compatíveis aos usuários na interface do app. Você transmite um SessionConfig, e ele retorna um booleano indicando se a combinação é compatível. Se você pretende vincular um SessionConfig com recursos obrigatórios, use essa API primeiro para garantir que ele seja compatível. 

Implementação na prática

Vamos ver como usar esses componentes para criar uma experiência de câmera melhor.

Cenário 1: modo de alta qualidade "Melhor esforço"

Se você quiser ativar os melhores recursos possíveis por padrão, forneça uma lista priorizada para preferredFeatureGroup. Neste exemplo, dizemos ao CameraX para priorizar o HDR, depois 60 FPS e, por fim, a estabilização de prévia. O CameraX lida com a complexidade de verificar todas as combinações possíveis e escolher a melhor compatível com o dispositivo.

Por exemplo, se um dispositivo puder processar HDR e 60 FPS juntos, mas não com a estabilização de prévia, o CameraX vai ativar os dois primeiros e descartar o terceiro. Assim, você tem a melhor experiência possível sem escrever verificações complexas e específicas do dispositivo.

  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)

        }

    }

)

Para este snippet de código, a CameraX vai tentar ativar combinações de recursos na seguinte ordem de prioridade, selecionando a primeira que o dispositivo oferece suporte total:

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

Cenário 2: como criar uma interface reativa

Para criar uma interface que responda às seleções do usuário e impeça que ele selecione uma combinação de recursos sem suporte, consulte o suporte diretamente. A função abaixo verifica quais recursos são incompatíveis com as seleções atuais do usuário, permitindo desativar os elementos correspondentes da interface.

  /**

 * 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

}

Em seguida, conecte essa lógica ao ViewModel ou controlador de UI para reagir à entrada do usuário e vincular novamente a câmera com uma configuração garantida.

  // 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,

        )

    )

}

Para conferir esses conceitos em um aplicativo funcional, acesse nosso app de teste interno. Ele oferece uma implementação completa dos cenários de "melhor esforço" e "UI reativa" discutidos acima.

Observação: este é um aplicativo de teste e não um exemplo com suporte oficial. Embora seja uma ótima referência para a API Feature Group, ela não foi refinada para uso em produção.

Começar hoje mesmo

A API Feature Group elimina a ambiguidade de trabalhar com recursos avançados de câmera. Ao fornecer uma maneira determinista de consultar o suporte a recursos, você pode criar apps de câmera mais eficientes e confiáveis com confiança.

A API está disponível como experimental no CameraX 1.5 e está programada para se tornar totalmente estável na versão 1.6, com mais suporte e melhorias a caminho.

Para saber mais, consulte a documentação oficial. Mal podemos esperar para ver o que você vai criar e receber seu feedback. Compartilhe sua opinião e informe problemas pelos seguintes canais:

Escrito por:

Continuar lendo