Новости о продуктах

Помимо отдельных функций: гарантированное сочетание функций с CameraX 1.5

6 минут чтения
Tahsin Masrur
Программист

Современные приложения для камер отличаются мощными, взаимосвязанными функциями. Пользователи ожидают возможности записывать видео с потрясающим HDR, снимать плавные движения со скоростью 60 кадров в секунду и получать идеально плавное видео с предварительной стабилизацией — зачастую всё это одновременно.

Разработчики понимают, что в реальности все гораздо сложнее. Как гарантировать, что конкретное устройство действительно поддерживает заданную комбинацию функций? До сих пор включение нескольких функций часто было рискованным делом. Можно было проверить поддержку отдельных функций, но их сочетание могло привести к непредсказуемому поведению или, что еще хуже, к сбою сеанса работы с камерой. Эта неопределенность заставляет разработчиков быть осторожными, что мешает пользователям устройств с поддержкой этой функции получить наилучший возможный опыт.

Например, лишь немногие устройства премиум-класса надежно поддерживают одновременное воспроизведение HDR и видео с частотой 60 кадров в секунду. Следовательно, большинство приложений избегают одновременного включения обеих функций, чтобы предотвратить ухудшение пользовательского опыта на большинстве телефонов.

Для решения этой проблемы мы представляем Feature Group в CameraX — новый API, разработанный для устранения подобных догадок. Теперь вы можете запросить информацию о поддержке определенной комбинации функций перед настройкой камеры или просто указать CameraX ваши приоритеты, и программа автоматически выберет наиболее подходящую комбинацию.

Для тех, кто впервые пользуется CameraX

Прежде чем мы углубимся в новый API групп функций, давайте кратко вспомним, что такое CameraX. CameraX — это библиотека поддержки Jetpack, созданная для упрощения разработки приложений для работы с камерой. Она предоставляет согласованный и простой в использовании API, работающий на большинстве устройств Android, с обратной совместимостью с Android 6.0 (уровень API 23). Если вы новичок в CameraX, мы рекомендуем ознакомиться с официальной документацией и попробовать выполнить практические задания , чтобы начать работу.

Что можно создать с помощью API групп функций

Вам больше не нужно рисковать, выбирая оптимальные комбинации функций, и вы можете уверенно обеспечивать наилучшие возможности камеры — например, одновременную съемку HDR и видео 60 кадров в секунду на производительном оборудовании (например, Pixel 10 Pro) — при этом избегая ошибок на устройствах, которые не поддерживают данную комбинацию.

unnamed.png

Pixel 10 Pro поддерживает одновременное использование HDR и 60 кадров в секунду.

unnamed (1).png

На старых устройствах, где HDR и 60 кадров в секунду не могут работать одновременно, включен только HDR, а опция 60 кадров в секунду отключена.

С помощью API групп объектов вы можете:

  • Создавайте более интеллектуальные и динамичные пользовательские интерфейсы: интеллектуально включайте или отключайте настройки в пользовательском интерфейсе в зависимости от поддержки оборудования в реальном времени. Например, если пользователь включает HDR, вы можете мгновенно сделать неактивной и отключить опцию 60 кадров в секунду, если эта комбинация не поддерживается на данном устройстве.
unsupported-features-disabled.gif
  • Обеспечьте надежный режим «Высокое качество»: настройте камеру, используя список желаемых функций с приоритетами. CameraX автоматически найдет и включит наилучшую поддерживаемую комбинацию для любого устройства, гарантируя отличный результат без сложной, специфичной для устройства логики.
  • Предотвратите сбои в работе камеры: предварительная проверка на совместимость предотвратит попытки камеры настроить неподдерживаемую комбинацию параметров, устранит распространенную причину сбоев и обеспечит бесперебойную работу пользователя.

Как это работает: основные компоненты

Новый API основан на ключевых дополнениях к SessionConfig и CameraInfo .

  1. GroupableFeature : Этот API предоставляет набор предопределенных группируемых функций, таких как HDR_HLG10 , FPS_60 , PREVIEW_STABILIZATION и IMAGE_ULTRA_HDR . Из-за вычислительных ограничений, только определенный набор функций может быть сгруппирован с высокой степенью надежности, обеспечиваемой этим API. Мы активно работаем над расширением этого списка и добавим поддержку большего количества функций в будущих релизах.
  2. Новые параметры SessionConfig : Этот класс, используемый для запуска сеанса работы с камерой, теперь принимает два новых параметра:
    • requiredFeatureGroup : Используйте это для функций, поддержка которых необходима для успешной настройки — идеально подходит для функций, которые пользователь явно включает, например, переключение переключателя «HDR». Для обеспечения детерминированного и согласованного взаимодействия вызов bindToLifecycle вызовет исключение IllegalArgumentException , если запрошенная комбинация не поддерживается, вместо того, чтобы молча игнорировать запрос на добавление функции. Для предварительного запроса этого результата следует использовать API CameraInfo#isFeatureGroupSupported (подробности ниже).
    • preferredFeatureGroup : Используйте этот параметр для желаемых, но необязательных функций, например, если вы хотите реализовать режим «Высокое качество» по умолчанию. Вы указываете список желаемых функций, упорядоченных в соответствии с вашими приоритетами , и CameraX автоматически включает комбинацию с наивысшим приоритетом, поддерживаемую устройством.
  3. CameraInfo#isFeatureGroupSupported() : Это основной метод запроса для явной проверки поддержки группы функций, хорошо подходящий для предоставления пользователям в пользовательском интерфейсе вашего приложения только поддерживаемых вариантов функций. Вы передаете ему объект SessionConfig , и он возвращает логическое значение, указывающее, поддерживается ли комбинация. Если вы планируете связать SessionConfig с необходимыми функциями, вам следует сначала использовать этот API, чтобы убедиться в его поддержке.

Внедрение на практике

Давайте рассмотрим, как использовать эти компоненты для улучшения работы с камерой.

Сценарий 1: Режим высокого качества «Максимальные усилия»

Если вы хотите включить наилучшие возможные функции по умолчанию, вы можете указать приоритетный список для параметра preferredFeatureGroup . В этом примере мы указываем CameraX отдавать приоритет HDR, затем 60 FPS и, наконец, стабилизации предварительного просмотра. CameraX обрабатывает сложную задачу проверки всех возможных комбинаций и выбора наилучшей из поддерживаемых устройством.

Например, если устройство может одновременно поддерживать HDR и 60 кадров в секунду, но не поддерживает стабилизацию изображения в режиме предварительного просмотра, CameraX включит первые две функции и отключит третью. Таким образом, вы получите наилучшие результаты без написания сложных проверок, специфичных для конкретного устройства.

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)

        }

    }

)

В этом фрагменте кода CameraX попытается включить комбинации функций в следующем порядке приоритета, выбрав первую из них, которую устройство полностью поддерживает:

  1. HDR + 60 кадров в секунду + стабилизация изображения в режиме предварительного просмотра
  2. HDR + 60 кадров в секунду
  3. HDR + Предварительный просмотр Стабилизация
  4. HDR
  5. 60 кадров в секунду + стабилизация предварительного просмотра
  6. 60 кадров в секунду
  7. Предварительная стабилизация
  8. Ни одна из вышеперечисленных особенностей

Сценарий 2: Создание реактивного пользовательского интерфейса

Чтобы создать пользовательский интерфейс, реагирующий на выбор пользователя и предотвращающий выбор неподдерживаемых комбинаций функций, вы можете напрямую обратиться в службу поддержки. Приведенная ниже функция проверяет, какие функции несовместимы с текущим выбором пользователя, позволяя отключить соответствующие элементы пользовательского интерфейса.

/**

 * 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

}

Затем вы можете интегрировать эту логику в свою ViewModel или контроллер пользовательского интерфейса, чтобы реагировать на ввод пользователя и повторно привязывать камеру с гарантированно работающей конфигурацией.

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

        )

    )

}

Чтобы увидеть эти концепции в работающем приложении, вы можете изучить наше внутреннее тестовое приложение . Оно предоставляет полную реализацию как сценария «максимальных усилий», так и сценария «реактивного пользовательского интерфейса», описанных выше.

Обратите внимание: это тестовое приложение, а не официально поддерживаемый пример. Хотя оно является отличным справочным материалом по API групп функций, оно не было доработано для использования в производственной среде.

Начните сегодня!

API групп функций устраняет неоднозначность при работе с расширенными возможностями камеры. Предоставляя детерминированный способ запроса поддержки функций, вы можете с уверенностью создавать более мощные и надежные приложения для работы с камерой.

API доступен в экспериментальном режиме в CameraX 1.5 и планируется к полной стабилизации в релизе 1.6, при этом в будущем будут добавлены новые функции и улучшения.

Чтобы узнать больше, ознакомьтесь с официальной документацией. Мы с нетерпением ждём ваших работ и будем рады вашим отзывам. Пожалуйста, делитесь своими мыслями и сообщайте о любых проблемах по следующим каналам:

    Продолжить чтение