اخبار محصول

فراتر از ویژگی‌های تکی: تضمین ترکیب‌های ویژگی با CameraX 1.5

‫۶ دقیقه خواندن
مشاهده نمایه تحسین مسرور
Tahsin Masrur مهندس نرم‌افزار

برنامه‌های دوربین مدرن با ویژگی‌های قدرتمند و هم‌پوشان تعریف می‌شوند. کاربران انتظار دارند ویدیو را با HDR خیره‌کننده ضبط کنند، حرکت روان را با نرخ ۶۰ فریم در ثانیه ثبت کنند، و با «لرزش‌گیر پیش‌نمایش» فیلمی بسیار روان بگیرند—اغلب همه این‌ها به‌طور هم‌زمان.

به‌عنوان توسعه‌دهنده، می‌دانیم که واقعیت پیچیده‌تر است. چگونه می‌توانید تضمین کنید که دستگاه خاصی واقعاً از ترکیب مشخصی پشتیبانی می‌کند؟ تاکنون، فعال کردن چندین ویژگی اغلب یک ریسک بود. می‌توانید پشتیبانی از ویژگی‌های فردی را بررسی کنید، اما ترکیب آن‌ها می‌تواند منجر به رفتار تعریف‌نشده یا بدتر از آن، ناموفق بودن جلسه دوربین شود.  این عدم قطعیت توسعه‌دهندگان را مجبور می‌کند که محافظه‌کار باشند، که این امر مانع از دسترسی کاربران دستگاه‌های توانمند به بهترین تجربه ممکن می‌شود.

برای مثال، تعداد بسیار کمی از دستگاه‌های ممتاز به‌طور هم‌زمان از HDR و ویدیو ۶۰ فریم در ثانیه پشتیبانی می‌کنند. درنتیجه، اکثر برنامه‌ها از فعال کردن هم‌زمان هر دو ویژگی خودداری می‌کنند تا از تجربه کاربری ضعیف در اکثر تلفن‌ها جلوگیری کنند.

برای رفع این مشکل، Feature Group را در CameraX معرفی می‌کنیم - یک میانای برنامه‌سازی کاربردی جدید که برای حذف این حدس‌وگمان طراحی شده است. اکنون می‌توانید قبل‌از پیکربندی دوربین، پرس‌وجو کنید که آیا ترکیب خاصی از ویژگی‌ها پشتیبانی می‌شود یا نه، یا به‌سادگی اولویت‌های خود را به CameraX بگویید و اجازه دهید بهترین ترکیب پشتیبانی‌شده را برای شما فعال کند.

برای کسانی که با CameraX آشنا نیستند

قبل‌از اینکه به Feature Group API جدید بپردازیم، بیایید به‌طور خلاصه یادآوری کنیم که CameraX چیست. CameraX یک کتابخانه پشتیبانی Jetpack است که برای کمک به شما در آسان‌تر کردن توسعه برنامه دوربین ساخته شده است. این میانای برنامه‌سازی کاربردی سطح API سازگار و با کاربرد آسانی ارائه می‌دهد که در اکثر دستگاه‌های Android کار می‌کند و با Android 6.0 (سطح API‏ ۲۳) سازگار با نسخه قدیمی است. اگر با CameraX آشنایی ندارید، توصیه می‌کنیم برای شروع به کار، اسناد رسمی را بررسی کنید و codelab را امتحان کنید.

آنچه می‌توانید با Feature Group API بسازید

دیگر نیازی نیست که ترکیب‌های مختلف ویژگی‌ها را امتحان کنید و می‌توانید با اطمینان بهترین تجربه‌های ممکن دوربین را ارائه دهید – مانند ویدیو HDR و ۶۰ فریم در ثانیه به‌طور هم‌زمان در سخت‌افزارهای توانمند (مثلاً Pixel 10 Pro) – و درعین‌حال به‌راحتی از بروز خطا در دستگاه‌هایی که از این ترکیب پشتیبانی نمی‌کنند جلوگیری کنید.

unnamed.png
‫Pixel 10 Pro که HDR و ۶۰ فریم در ثانیه را به‌طور هم‌زمان فعال می‌کند
unnamed (1).png
در دستگاه‌های قدیمی‌تر که HDR و ۶۰ فریم در ثانیه نمی‌توانند هم‌زمان اجرا شوند، فقط HDR فعال می‌شود و گزینه ۶۰ فریم در ثانیه غیرفعال می‌شود.

با Feature Group API می‌توانید:

  • ساختن میاناهای کاربر پویاتر و هوشمندتر: تنظیمات را در میانای کاربر به‌طور هوشمندانه براساس پشتیبانی سخت‌افزاری هم‌زمان فعال یا غیرفعال کنید. برای مثال، اگر کاربر HDR را فعال کند، می‌توانید فوراً گزینه ۶۰ فریم در ثانیه را خاکستری و غیرفعال کنید، اگر این ترکیب در آن دستگاه پشتیبانی نمی‌شود. 
hdr.gif
  • ارائه حالت «کیفیت بالا» قابل‌اطمینان: دوربین را با فهرست اولویت‌بندی‌شده‌ای از ویژگی‌های مطلوب پیکربندی کنید. CameraX به‌طور خودکار بهترین ترکیب پشتیبانی‌شده را برای هر دستگاهی پیدا و فعال می‌کند و نتیجه‌ای عالی را بدون منطق پیچیده و مختص دستگاه تضمین می‌کند.
  • جلوگیری از خرابی جلسه دوربین: با تأیید پشتیبانی ازقبل، از تلاش دوربین برای پیکربندی ترکیب پشتیبانی‌نشده جلوگیری می‌کنید، منبع رایج ازکارافتادگی را حذف می‌کنید، و تجربه کاربری روانی ارائه می‌دهید.

نحوه عملکرد: مؤلفه‌های اصلی

میانای برنامه‌سازی کاربردی جدید بر افزوده‌های کلیدی به SessionConfig و CameraInfo متمرکز است.

  1. GroupableFeature: این میانای برنامه‌سازی کاربردی مجموعه‌ای از ویژگی‌های قابل‌گروه‌بندی ازپیش تعریف‌شده را معرفی می‌کند، مانند HDR_HLG10، FPS_60، PREVIEW_STABILIZATION، و IMAGE_ULTRA_HDR. به‌دلیل محدودیت‌های محاسباتی، فقط مجموعه خاصی از ویژگی‌ها را می‌توان با درجه بالایی از اطمینان که این میانای برنامه‌سازی کاربردی ارائه می‌دهد گروه‌بندی کرد. ما فعالانه در تلاشیم تا این فهرست را گسترش دهیم و در نسخه‌های بعدی از ویژگی‌های بیشتری پشتیبانی خواهیم کرد.
     
  2. پارامترهای جدید SessionConfig: این کلاس که برای شروع جلسه دوربین استفاده می‌شود، اکنون دو پارامتر جدید را می‌پذیرد:
    • requiredFeatureGroup: از این مورد برای ویژگی‌هایی استفاده کنید که باید پشتیبانی شوند تا پیکربندی موفقیت‌آمیز باشد - ایده‌آل برای ویژگی‌هایی که کاربر صریحاً فعال می‌کند، مانند روشن/خاموش کردن کلید «HDR». برای اطمینان از تجربه‌ای قطعی و هماهنگ، اگر ترکیب درخواستی پشتیبانی نشود، فراخوانی bindToLifecycle به‌جای نادیده گرفتن بی‌صدای درخواست ویژگی، IllegalArgumentException را برمی‌گرداند. CameraInfo#isFeatureGroupSupported API (جزئیات زیر) باید برای پرس‌وجو از این نتیجه ازقبل استفاده شود.
    • preferredFeatureGroup: از این مورد برای ویژگی‌هایی استفاده کنید که مطلوب اما اختیاری هستند، مثلاً وقتی می‌خواهید حالت پیش‌فرض «کیفیت بالا» را پیاده‌سازی کنید. فهرستی از ویژگی‌های موردنظرتان را به‌ترتیب اولویت ارائه می‌دهید و CameraX به‌طور خودکار ترکیب دارای بالاترین اولویت را که دستگاه پشتیبانی می‌کند فعال می‌کند.
  3. CameraInfo#isFeatureGroupSupported(): این روش اصلی پُرسمان برای بررسی صریح پشتیبانی شدن گروه ویژگی است و برای ارائه گزینه‌های ویژگی پشتیبانی‌شده به کاربران در واسط کاربر برنامه شما بسیار مناسب است. SessionConfig را به آن می‌دهید و یک مقدار بولی برمی‌گرداند که نشان می‌دهد آیا این ترکیب پشتیبانی می‌شود یا نه. اگر قصد دارید SessionConfig را با ویژگی‌های الزامی مقید کنید، باید ابتدا از این میانای برنامه‌سازی کاربردی استفاده کنید تا مطمئن شوید پشتیبانی می‌شود. 

پیاده‌سازی در عمل

بیایید ببینیم چگونه می‌توان از این مؤلفه‌ها برای ساختن تجربه دوربین بهتر استفاده کرد.

سناریو ۱: حالت کیفیت بالا با «بهترین تلاش»

اگر می‌خواهید بهترین ویژگی‌های ممکن را به‌طور پیش‌فرض فعال کنید، می‌توانید فهرست اولویت‌بندی‌شده‌ای به preferredFeatureGroup ارائه دهید. در این مثال، به CameraX می‌گوییم که HDR را در اولویت قرار دهد، سپس ۶۰ فریم در ثانیه، و درنهایت «لرزش‌گیر پیش‌نمایش». CameraX پیچیدگی بررسی همه ترکیب‌های ممکن و انتخاب بهترین ترکیبی را که دستگاه پشتیبانی می‌کند مدیریت می‌کند.

برای مثال، اگر دستگاهی بتواند HDR و ۶۰ فریم در ثانیه را باهم مدیریت کند اما نتواند «لرزش‌گیر پیش‌نمایش» را مدیریت کند، 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 +‏ ۶۰ فریم در ثانیه + لرزش‌گیر پیش‌نمایش
  2. HDR +‏ ۶۰ فریم در ثانیه
  3. HDR + لرزش‌گیر پیش‌نمایش
  4. HDR
  5. ‫۶۰ فریم در ثانیه + لرزش‌گیر پیش‌نمایش
  6. 60 FPS
  7. پیش‌نمایش لرزش‌گیر
  8. هیچ‌کدام از ویژگی‌های بالا

سناریو ۲: ساختن واسط کاربر واکنشی

برای ایجاد واسط کاربری‌ای که به انتخاب‌های کاربر پاسخ دهد و از انتخاب ترکیب ویژگی‌های پشتیبانی‌نشده توسط کاربران جلوگیری کند، می‌توانید مستقیماً برای پشتیبانی پُرسمان کنید. تابع زیر بررسی می‌کند که کدام ویژگی‌ها با انتخاب‌های فعلی کاربر ناسازگار هستند و به شما امکان می‌دهد عناصر میانای کاربر مربوطه را غیرفعال کنید.

/**

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

        )

    )

}

برای دیدن این مفاهیم در یک برنامه کاربردی، می‌توانید برنامه آزمایشی داخلی ما را کاوش کنید. این برنامه پیاده‌سازی کاملی از هر دو سناریو «بهترین تلاش» و «رابط کاربری واکنشی» که در بالا بحث شد ارائه می‌دهد.

لطفاً توجه داشته باشید: این یک برنامه آزمایشی است و نمونه‌ای نیست که به‌طور رسمی پشتیبانی شود. اگرچه این برنامه مرجع خوبی برای Feature Group API است، اما برای استفاده در محیط تولید بهینه‌سازی نشده است.

امروز شروع کنید

Feature Group API ابهام کار با قابلیت‌های پیشرفته دوربین را برطرف می‌کند. با ارائه روشی قطعی برای پرسمان درباره پشتیبانی از ویژگی، می‌توانید برنامه‌های دوربین قدرتمندتر و قابل‌اعتمادتری را با اطمینان بسازید.

این میانای برنامه‌سازی کاربردی به‌صورت آزمایشی در CameraX 1.5 دردسترس است و قرار است در نسخه ۱.۶ کاملاً پایدار شود و پشتیبانی و بهبودهای بیشتری در راه است.

برای کسب اطلاعات بیشتر، به اسناد رسمی مراجعه کنید. بی‌صبرانه منتظریم ببینیم چه چیزی خلق می‌کنید و مشتاقانه منتظر بازخوردتان هستیم. لطفاً ازطریق کانال‌های زیر، نظراتتان را با ما درمیان بگذارید و مشکلات را گزارش کنید:

نویسنده:
ادامه خواندن