প্রয়োজনীয় অনুমতি চেয়ে তা পেয়ে গেলে, আপনার অ্যাপটি এআই গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে পারবে। ফোনের হার্ডওয়্যারের পরিবর্তে গ্লাসের হার্ডওয়্যার অ্যাক্সেস করার মূল উপায় হলো একটি প্রোজেক্টেড কনটেক্সট ব্যবহার করা।
আপনার কোড কোথায় এক্সিকিউট হচ্ছে তার উপর নির্ভর করে, প্রজেক্টেড কনটেক্সট পাওয়ার দুটি প্রধান উপায় রয়েছে:
আপনার কোড যদি এআই গ্লাসেস অ্যাক্টিভিটিতে চলে, তাহলে একটি প্রজেক্টেড কনটেক্সট পান।
যদি আপনার অ্যাপের কোড আপনার এআই গ্লাস অ্যাক্টিভিটির ভেতর থেকে চলে, তাহলে এর নিজস্ব অ্যাক্টিভিটি কনটেক্সটটি ইতিমধ্যেই একটি প্রোজেক্টেড কনটেক্সট হয়ে যায়। এই পরিস্থিতিতে, ওই অ্যাক্টিভিটির ভেতর থেকে করা কলগুলো আগে থেকেই গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে পারে।
ফোন অ্যাপ কম্পোনেন্টে চলমান কোডের জন্য একটি প্রজেক্টেড কনটেক্সট পান।
আপনার অ্যাপের কোনো অংশ যদি আপনার এআই গ্লাস অ্যাক্টিভিটির বাইরে (যেমন ফোন অ্যাক্টিভিটি বা কোনো সার্ভিস) গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে চায়, তবে তাকে অবশ্যই স্পষ্টভাবে একটি প্রোজেক্টেড কনটেক্সট সংগ্রহ করতে হবে। এটি করার জন্য, ` createProjectedDeviceContext() মেথডটি ব্যবহার করুন:
@OptIn(ExperimentalProjectedApi::class) private fun getGlassesContext(context: Context): Context? { return try { // From a phone Activity or Service, get a context for the AI glasses. ProjectedContext.createProjectedDeviceContext(context) } catch (e: IllegalStateException) { Log.e(TAG, "Failed to create projected device context", e) null } }
বৈধতা যাচাই করুন
প্রজেক্টেড কনটেক্সট তৈরি করার পর, ProjectedContext.isProjectedDeviceConnected মেথডটি মনিটর করুন। যতক্ষণ এই মেথডটি true রিটার্ন করে, ততক্ষণ প্রজেক্টেড কনটেক্সটটি সংযুক্ত ডিভাইসটির জন্য বৈধ থাকে এবং আপনার ফোন অ্যাপের অ্যাক্টিভিটি বা সার্ভিস (যেমন CameraManager ) এআই গ্লাসের হার্ডওয়্যার অ্যাক্সেস করতে পারে।
সংযোগ বিচ্ছিন্ন হলে পরিষ্কার করুন
প্রজেক্টেড কনটেক্সটটি সংযুক্ত ডিভাইসের লাইফসাইকেলের সাথে যুক্ত থাকে, তাই ডিভাইসটি সংযোগ বিচ্ছিন্ন হলে এটিও নষ্ট হয়ে যায়। ডিভাইসটি সংযোগ বিচ্ছিন্ন হলে, ProjectedContext.isProjectedDeviceConnected ফলস false ) রিটার্ন করে। আপনার অ্যাপের উচিত এই পরিবর্তনটি পর্যবেক্ষণ করা এবং সেই প্রজেক্টেড কনটেক্সট ব্যবহার করে তৈরি করা যেকোনো সিস্টেম সার্ভিস (যেমন CameraManager ) বা রিসোর্স পরিষ্কার করে ফেলা।
পুনরায় সংযোগ করার সময় পুনরায় শুরু করুন
যখন এআই গ্লাস ডিভাইসটি পুনরায় সংযোগ স্থাপন করে, তখন আপনার অ্যাপ createProjectedDeviceContext() ব্যবহার করে আরেকটি প্রোজেক্টেড কনটেক্সট ইনস্ট্যান্স পেতে পারে এবং তারপর সেই নতুন প্রোজেক্টেড কনটেক্সট ব্যবহার করে যেকোনো সিস্টেম সার্ভিস বা রিসোর্স পুনরায় ইনিশিয়ালাইজ করতে পারে।
ব্লুটুথ ব্যবহার করে অডিও অ্যাক্সেস করুন
বর্তমানে, এআই গ্লাস আপনার ফোনের সাথে একটি সাধারণ ব্লুটুথ অডিও ডিভাইস হিসেবে সংযুক্ত হয়। হেডসেট এবং A2DP (অ্যাডভান্সড অডিও ডিস্ট্রিবিউশন প্রোফাইল) উভয় প্রোফাইলই সমর্থিত। এই পদ্ধতি ব্যবহার করে, অডিও ইনপুট বা আউটপুট সমর্থন করে এমন যেকোনো অ্যান্ড্রয়েড অ্যাপ গ্লাসে কাজ করতে পারে, এমনকি যদি অ্যাপটি বিশেষভাবে গ্লাস সমর্থন করার জন্য তৈরি না-ও হয়ে থাকে। কিছু ক্ষেত্রে, প্রজেক্টেড কনটেক্সট ব্যবহার করে গ্লাসের হার্ডওয়্যার অ্যাক্সেস করার বিকল্প হিসেবে আপনার অ্যাপের ব্যবহারের জন্য ব্লুটুথ ব্যবহার করা আরও ভালো হতে পারে।
যেকোনো সাধারণ ব্লুটুথ অডিও ডিভাইসের মতোই, RECORD_AUDIO পারমিশন দেওয়ার ক্ষমতা ফোন দ্বারা নিয়ন্ত্রিত হয়, চশমা দ্বারা নয়।
এআই গ্লাসের ক্যামেরা দিয়ে একটি ছবি তুলুন
এআই গ্লাসের ক্যামেরা দিয়ে ছবি তোলার জন্য, আপনার অ্যাপের জন্য সঠিক কনটেক্সট ব্যবহার করে CameraX-এর ImageCapture ইউজ কেসটি গ্লাসের ক্যামেরার সাথে সেট আপ ও বাইন্ড করুন:
private fun startCameraOnGlasses(activity: ComponentActivity) { // 1. Get the CameraProvider using the projected context. // When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera. val projectedContext = try { ProjectedContext.createProjectedDeviceContext(activity) } catch (e: IllegalStateException) { Log.e(TAG, "AI Glasses context could not be created", e) return } val cameraProviderFuture = ProcessCameraProvider.getInstance(projectedContext) cameraProviderFuture.addListener({ val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get() val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA // 2. Check for the presence of a camera. if (!cameraProvider.hasCamera(cameraSelector)) { Log.w(TAG, "The selected camera is not available.") return@addListener } // 3. Query supported streaming resolutions using Camera2 Interop. val cameraInfo = cameraProvider.getCameraInfo(cameraSelector) val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo) val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP ) // 4. Define the resolution strategy. val targetResolution = Size(1920, 1080) val resolutionStrategy = ResolutionStrategy( targetResolution, ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER ) val resolutionSelector = ResolutionSelector.Builder() .setResolutionStrategy(resolutionStrategy) .build() // 5. If you have other continuous use cases bound, such as Preview or ImageAnalysis, // you can use Camera2 Interop's CaptureRequestOptions to set the FPS val fpsRange = Range(30, 60) val captureRequestOptions = CaptureRequestOptions.Builder() .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange) .build() // 6. Initialize the ImageCapture use case with options. val imageCapture = ImageCapture.Builder() // Optional: Configure resolution, format, etc. .setResolutionSelector(resolutionSelector) .build() try { // Unbind use cases before rebinding. cameraProvider.unbindAll() // Bind use cases to camera using the Activity as the LifecycleOwner. cameraProvider.bindToLifecycle( activity, cameraSelector, imageCapture ) } catch (exc: Exception) { Log.e(TAG, "Use case binding failed", exc) } }, ContextCompat.getMainExecutor(activity)) }
কোড সম্পর্কে মূল বিষয়গুলো
- প্রজেক্টেড ডিভাইস কনটেক্সট ব্যবহার করে
ProcessCameraProviderএর একটি ইনস্ট্যান্স সংগ্রহ করে। - প্রক্ষেপিত প্রেক্ষাপটের পরিধির মধ্যে, ক্যামেরা নির্বাচন করার সময় এআই চশমার প্রাথমিক, বাইরের দিকে মুখ করা ক্যামেরাটি
DEFAULT_BACK_CAMERAতে ম্যাপ করা হয়। - অগ্রসর হওয়ার আগে, নির্বাচিত ক্যামেরাটি ডিভাইসে উপলব্ধ আছে কিনা তা যাচাই করার জন্য
cameraProvider.hasCamera(cameraSelector)ব্যবহার করে একটি প্রি-বাইন্ডিং চেক করা হয়। - অন্তর্নিহিত
CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAPপড়ার জন্যCamera2CameraInfoএর সাথে Camera2 Interop ব্যবহার করে, যা সমর্থিত রেজোলিউশনগুলির উপর উন্নত যাচাইয়ের জন্য উপযোগী হতে পারে। -
ImageCaptureএর আউটপুট ছবির রেজোলিউশন নিখুঁতভাবে নিয়ন্ত্রণ করার জন্য একটি কাস্টমResolutionSelectorতৈরি করা হয়েছে। - একটি
ImageCaptureব্যবহারের ক্ষেত্র তৈরি করে যা একটি কাস্টমResolutionSelectorদিয়ে কনফিগার করা থাকে। - এটি
ImageCaptureইউজ কেসটিকে অ্যাক্টিভিটির লাইফসাইকেলের সাথে সংযুক্ত করে। এটি অ্যাক্টিভিটির অবস্থার উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে ক্যামেরা খোলা এবং বন্ধ করা পরিচালনা করে (উদাহরণস্বরূপ, অ্যাক্টিভিটি পজ করা হলে ক্যামেরা বন্ধ করে দেওয়া)।
এআই গ্লাসের ক্যামেরা সেট আপ করার পরে, আপনি CameraX-এর ImageCapture ক্লাস ব্যবহার করে একটি ছবি তুলতে পারবেন। takePicture() ব্যবহার করে কীভাবে ছবি তুলতে হয় , তা জানতে CameraX-এর ডকুমেন্টেশন দেখুন।
এআই চশমার ক্যামেরা দিয়ে একটি ভিডিও ধারণ করুন
এআই গ্লাসের ক্যামেরা দিয়ে ছবির পরিবর্তে ভিডিও ক্যাপচার করতে, ImageCapture কম্পোনেন্টগুলোকে সংশ্লিষ্ট VideoCapture কম্পোনেন্ট দিয়ে প্রতিস্থাপন করুন এবং ক্যাপচার এক্সিকিউশন লজিক পরিবর্তন করুন।
প্রধান পরিবর্তনগুলোর মধ্যে রয়েছে একটি ভিন্ন ইউজ কেস ব্যবহার করা, একটি ভিন্ন আউটপুট ফাইল তৈরি করা এবং উপযুক্ত ভিডিও রেকর্ডিং পদ্ধতি ব্যবহার করে ক্যাপচার শুরু করা। VideoCapture API এবং এটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, CameraX-এর ভিডিও ক্যাপচার ডকুমেন্টেশন দেখুন।
নিম্নলিখিত সারণিতে আপনার অ্যাপের ব্যবহারের ধরনের উপর নির্ভর করে প্রস্তাবিত রেজোলিউশন এবং ফ্রেম রেট দেখানো হলো:
| ব্যবহারের ক্ষেত্র | সমাধান | ফ্রেম রেট |
|---|---|---|
| ভিডিও যোগাযোগ | ১২৮০ x ৭২০ | ১৫ এফপিএস |
| কম্পিউটার ভিশন | ৬৪০ x ৪৮০ | ১০ এফপিএস |
| এআই ভিডিও স্ট্রিমিং | ৬৪০ x ৪৮০ | ১ এফপিএস |
এআই গ্লাস অ্যাক্টিভিটি থেকে ফোনের হার্ডওয়্যার অ্যাক্সেস করুন
একটি AI গ্লাস অ্যাক্টিভিটি createHostDeviceContext(context) ব্যবহার করে হোস্ট ডিভাইসের (ফোনের) কনটেক্সট পাওয়ার মাধ্যমে ফোনের হার্ডওয়্যারও (যেমন ক্যামেরা বা মাইক্রোফোন) অ্যাক্সেস করতে পারে:
@OptIn(ExperimentalProjectedApi::class) private fun getPhoneContext(activity: ComponentActivity): Context? { return try { // From an AI glasses Activity, get a context for the phone. ProjectedContext.createHostDeviceContext(activity) } catch (e: IllegalStateException) { Log.e(TAG, "Failed to create host device context", e) null } }
একটি হাইব্রিড অ্যাপে (যে অ্যাপে মোবাইল এবং এআই গ্লাস উভয় অভিজ্ঞতাই থাকে) হোস্ট ডিভাইসের (ফোন) জন্য নির্দিষ্ট হার্ডওয়্যার বা রিসোর্স অ্যাক্সেস করার সময়, আপনার অ্যাপটি যাতে সঠিক হার্ডওয়্যার অ্যাক্সেস করতে পারে তা নিশ্চিত করার জন্য আপনাকে অবশ্যই সঠিক কনটেক্সট স্পষ্টভাবে নির্বাচন করতে হবে:
- ফোনের কনটেক্সট পেতে ফোন
ActivityথেকেActivityকনটেক্সট অথবাProjectedContext.createHostDeviceContext()ব্যবহার করুন। -
getApplicationContext()ব্যবহার করবেন না, কারণ যদি কোনো গ্লাসেস অ্যাক্টিভিটি সর্বশেষ চালু হওয়া কম্পোনেন্ট হয়ে থাকে, তাহলে অ্যাপ্লিকেশন কনটেক্সট ভুলভাবে এআই গ্লাসেসের কনটেক্সট রিটার্ন করতে পারে।