إطلاق الإصدار 1.5 من CameraX: تسجيل فيديوهات قوي والتقاط صور احترافي
مدّة القراءة: 7 دقائق
يسرّ فريق CameraX الإعلان عن إطلاق الإصدار 1.5. يركّز هذا التحديث الأخير على توفير إمكانات احترافية بين يديك مع تسهيل عملية ضبط إعدادات جلسة الكاميرا أكثر من أي وقت مضى.
بالنسبة إلى تسجيل الفيديو، يمكن للمستخدمين الآن تسجيل فيديوهات رائعة بالحركة البطيئة أو بمعدل لقطات مرتفع بسهولة. والأهم من ذلك، تتيح لك Feature Group API الجديدة تفعيل مجموعات معقّدة مثل HDR بمعدل 10 بت و60 لقطة في الثانية بثقة، ما يضمن تحقيق نتائج متّسقة على جميع الأجهزة المتوافقة.
في ما يتعلق بالتقاط الصور، يمكنك الاستفادة من أقصى قدر من المرونة من خلال إمكانية التقاط ملفات DNG (RAW) غير معالَجة وغير مضغوطة. بالإضافة إلى ذلك، يمكنك الآن الاستفادة من ميزة Ultra HDR حتى عند استخدام "إضافات الكاميرا" القوية.
تستند هذه الميزات إلى SessionConfig API الجديدة التي تسهّل عملية إعداد الكاميرا وإعادة ضبطها. لنستعرض الآن تفاصيل هذه الميزات الجديدة الرائعة.
تسجيل فيديو فعّال: سرعة عالية ومجموعات من الميزات
توسّع الإصدار 1.5 من CameraX بشكل كبير إمكانات الفيديو، ما يتيح تجارب تسجيل أكثر إبداعًا وقوة.
فيديو التصوير البطيء ومعدّل اللقطات المرتفع في الثانية
أصبحت ميزة "الفيديو بالحركة البطيئة" متاحة الآن، وهي إحدى الميزات التي كنّا نتطلّع إلى إطلاقها. يمكنك الآن تسجيل فيديو عالي السرعة (مثل 120 أو 240 لقطة في الثانية) وترميزه مباشرةً في فيديو بطيء الحركة. بدلاً من ذلك، يمكنك التسجيل بعدد اللقطات المرتفع نفسه في الثانية لإنتاج فيديو سلس للغاية.
يمكنك تنفيذ ذلك بسهولة إذا كنت على دراية بواجهة برمجة التطبيقات VideoCapture.
1. التحقّق من توفّر ميزة "التقاط الفيديو بسرعة عالية": استخدِم طريقة Recorder.getHighSpeedVideoCapabilities() الجديدة للاستعلام عمّا إذا كان الجهاز يتيح استخدام هذه الميزة.
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)
if (highSpeedCapabilities == null) {
// This camera device does not support high-speed video.
return
}2. ضبط حالة الاستخدام وربطها: استخدِم videoCapabilities الذي تم عرضه (والذي يحتوي على معلومات حول جودة الفيديو المتوافقة) لإنشاء HighSpeedVideoSessionConfig. عليك بعد ذلك طلب نطاقات عدد اللقطات في الثانية المتوافقة من خلال cameraInfo.getSupportedFrameRateRanges() وتحديد النطاق المطلوب. استخدِم setSlowMotionEnabled(true) لتسجيل فيديوهات بالتصوير البطيء، وإلا سيتم تسجيل فيديوهات بمعدل لقطات مرتفع. الخطوة الأخيرة هي استخدام Recorder.prepareRecording().start() العادي لبدء تسجيل الفيديو.
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, {})التوافق والقيود
يتطلّب التسجيل العالي السرعة توفُّر CameraConstrainedHighSpeedCaptureSession وCamcorderProfile محدّدين. يجب إجراء عملية التحقّق من الإمكانات دائمًا، وتفعيل التسجيل عالي السرعة على الأجهزة المتوافقة فقط لتجنُّب تقديم تجربة سيئة للمستخدم. تتوفّر هذه الميزة حاليًا على الكاميرات الخلفية في جميع هواتف Pixel تقريبًا وطُرز محدّدة من الشركات المصنّعة الأخرى.
يمكنك الاطّلاع على منشور المدونة لمزيد من التفاصيل.
الجمع بين الميزات بثقة: Feature Group API
يقدّم الإصدار 1.5 من CameraX واجهة برمجة التطبيقات لمجموعة الميزات التي تزيل التخمين بشأن توافق الميزات. استنادًا إلى واجهة برمجة التطبيقات الخاصة بطلب الجمع بين الميزات في Android 15، يمكنك الآن تفعيل ميزات متعددة معًا بثقة، ما يضمن جلسة كاميرا ثابتة. تتوافق "مجموعة الميزات" حاليًا مع: النطاق العالي الديناميكية (HLG) و60 لقطة في الثانية وتثبيت المعاينة ودقة HDR الفائقة. على سبيل المثال، يمكنك تفعيل ميزات "النطاق العالي الديناميكية" و"60 إطارًا في الثانية" و"تثبيت المعاينة" في الوقت نفسه على هواتف Pixel 10 وسلسلة Galaxy S25. نخطّط لإضافة تحسينات مستقبلية تشمل التسجيل بدقة 4K والتكبير/التصغير الفائق.
تتيح واجهة برمجة التطبيقات لمجموعات الميزات حالتَي استخدام أساسيتَين:
حالة الاستخدام 1: تحديد أولويات الجودة الأفضل
إذا كنت تريد تسجيل اللقطات باستخدام أفضل مجموعة ممكنة من الميزات، يمكنك تقديم قائمة ذات أولوية. ستحاول CameraX تفعيلها بالترتيب، مع اختيار المجموعة الأولى التي يتوافق معها الجهاز تمامًا.
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)في هذا المثال، تحاول CameraX تفعيل الميزات بهذا الترتيب:
- النطاق الديناميكي العالي (HDR) + 60 لقطة في الثانية + تثبيت المعاينة
- نطاق عالي الديناميكية (HDR) + 60 لقطة في الثانية
- تثبيت الصورة مع تقنية HDR والمعاينة
- نطاق عالي الديناميكية
- 60 لقطة في الثانية + تثبيت المعاينة
- 60 لقطة في الثانية
- معاينة التثبيت
- بدون
حالة الاستخدام 2: إنشاء واجهة مستخدم للإعدادات موجّهة للمستخدمين
يمكنك الآن عرض مجموعات الميزات المتوافقة في واجهة مستخدم إعدادات تطبيقك بدقة، وإيقاف أزرار التبديل للخيارات غير المتوافقة، مثل الصورة أدناه.
لتحديد ما إذا كان يجب إيقاف زر التبديل، استخدِم الرموز التالية للتحقّق من إمكانية استخدام مجموعة من الميزات. في البداية، استعلم عن حالة كل ميزة على حدة. بعد تفعيل إحدى الميزات، أعِد طلب الميزات المتبقية مع الميزات المفعّلة لمعرفة ما إذا كان يجب الآن إيقافها بسبب قيود التوافق.
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
}
}يُرجى الرجوع إلى منشور المدوّنة حول "مجموعة الميزات" لمزيد من المعلومات.
المزيد من تحسينات الفيديو
- تحسينات على استخدام الكاميرا بشكل متزامن: باستخدام CameraX 1.5.1، يمكنك الآن ربط حالات استخدام "المعاينة" و"التقاط الصور" و"تسجيل الفيديو" بشكل متزامن لكل SingleCameraConfig في وضع عدم التكوين. بالإضافة إلى ذلك، في وضع الدمج (حالات الاستخدام نفسها مع CompositionSettings)، يمكنك الآن ضبط
CameraEffectالذي يتم تطبيقه على نتيجة الدمج النهائية. - كتم الصوت بشكل ديناميكي: يمكنك الآن بدء التسجيل في وضع كتم الصوت باستخدام
PendingRecording.withAudioEnabled(boolean initialMuted)والسماح للمستخدم بإلغاء كتم الصوت لاحقًا باستخدامRecording.mute(boolean muted). - تحسين معالجة مساحة التخزين غير الكافية: ترسل CameraX الآن الخطأ
VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGEبشكل موثوق، ما يتيح لتطبيقك معالجة حالات مساحة التخزين المنخفضة بشكل سليم وإبلاغ المستخدم. - تحسين الإضاءة المنخفضة: على الأجهزة المتوافقة (مثل سلسلة هواتف Pixel 10)، يمكنك تفعيل CameraControl.enableLowLightBoostAsync لزيادة سطوع المعاينة وتيارات الفيديو تلقائيًا في البيئات المظلمة.
التقاط صور احترافي
يقدّم الإصدار 1.5 من CameraX تحسينات كبيرة على ImageCapture للمطوّرين الذين يطلبون أعلى مستوى من الجودة والمرونة.
إطلاق العنان للتحكّم الإبداعي باستخدام ميزة التقاط صور بتنسيق DNG (RAW)
للحصول على تحكّم كامل في المعالجة اللاحقة، تتيح CameraX الآن إمكانية التقاط صور بتنسيق DNG (RAW). يتيح لك ذلك الوصول إلى بيانات الصور غير المعالَجة وغير المضغوطة مباشرةً من مستشعر الكاميرا، ما يتيح لك إجراء تعديلات وتصحيح الألوان بمستوى احترافي. تتيح واجهة برمجة التطبيقات إمكانية التقاط ملف DNG وحده أو التقاط مخرجات JPEG وDNG في الوقت نفسه. اطّلِع على الرمز النموذجي أدناه لمعرفة كيفية التقاط ملفات JPEG وDNG في الوقت نفسه.
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) {}
}
)دقة HDR فائقة لإضافات الكاميرا
يمكنك الاستفادة من أفضل الميزات، مثل التصوير الحاسوبي المذهل الذي توفّره "إضافات الكاميرا" (مثل "الوضع الليلي") إلى جانب الألوان الرائعة والنطاق الديناميكي العالي الذي توفّره ميزة دقة HDR فائقة. تتوفّر هذه الميزة الآن على العديد من هواتف Android المميّزة الحديثة، مثل سلسلة هواتف Pixel 9/10 وسلسلة هواتف 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()تحسينات على واجهة برمجة التطبيقات الأساسية وسهولة الاستخدام
طريقة جديدة لإعداد التقارير: SessionConfig
كما هو موضّح في الأمثلة أعلاه، SessionConfig هو مفهوم جديد في CameraX 1.5. تعمل هذه الواجهة على مركزية الإعدادات وتبسّط واجهة برمجة التطبيقات بطريقتَين رئيسيتَين:
- لا حاجة إلى طلبات
unbind()يدوية: تتوافق واجهات برمجة التطبيقات في CameraX مع مراحل النشاط. سيؤدي ذلك إلى "إلغاء ربط" حالات الاستخدام ضِمنيًا عند إيقاف النشاط أوLifecycleOwnerالأخرى. ومع ذلك، يتطلّب تعديل حالات الاستخدام أو تبديل الكاميرات الاتصال بالرقمunbind()أوunbindAll()قبل إعادة الربط. باستخدام CameraX 1.5، عند ربطSessionConfigجديد، تعدّل CameraX الجلسة بسلاسة نيابةً عنك، ما يلغي الحاجة إلى طلبات إلغاء الربط. - التحكّم الحتمي في عدد اللقطات في الثانية: تقدّم واجهة برمجة التطبيقات
SessionConfigالجديدة طريقة حتمية لإدارة عدد اللقطات في الثانية. على عكسsetTargetFrameRateالسابق الذي كان مجرد تلميح، تضمن هذه الطريقة الجديدة تطبيق نطاق معدّل اللقطات المحدّد عند إعدادها بنجاح. لضمان الدقة، يجب طلب معدّلات الإطارات المتوافقة باستخدامCameraInfo.getSupportedFrameRateRanges(SessionConfig). من خلال تمريرSessionConfigالكامل، يمكن لـ CameraX تحديد النطاقات المتوافقة بدقة استنادًا إلى إعدادات البث.
أصبحت ميزة "تركيب الصور" في الكاميرا أكثر ثباتًا
نعلم مدى إعجابك بإطار عمل Jetpack Compose، ويسرّنا الإعلان عن أنّ مكتبة camera-compose أصبحت الآن إصدارًا ثابتًا برقم 1.5.1! يتضمّن هذا الإصدار إصلاحات لأخطاء مهمة تتعلّق باستخدام CameraXViewfinder مع ميزات Compose، مثل moveableContentOf وPager، بالإضافة إلى حلّ مشكلة تمديد المعاينة. سنواصل إضافة المزيد من الميزات إلى camera-compose في الإصدارات المستقبلية.
تحسينات على ImageAnalysis وCameraControl
- تعديل قوة المصباح اليدوي: يمكنك التحكّم بدقة في المصباح اليدوي للجهاز باستخدام واجهات برمجة التطبيقات الجديدة. يمكنك طلب الحد الأقصى لمستوى الإضاءة المتاح باستخدام CameraInfo.getMaxTorchStrengthLevel()، ثم ضبط المستوى المطلوب باستخدام CameraControl.setTorchStrengthLevel().
- إتاحة NV21 في
ImageAnalysis: يمكنك الآن طلب تنسيق الصورة NV21 مباشرةً منImageAnalysis، ما يسهّل عملية الدمج مع المكتبات وواجهات برمجة التطبيقات الأخرى. يتم تفعيل هذه الميزة من خلال استدعاءImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).
ابدأ اليوم
حدِّث التبعيات إلى CameraX 1.5 اليوم واستكشِف الميزات الجديدة الرائعة. نتطلّع إلى رؤية ابتكاراتك.
لاستخدام CameraX 1.5، يُرجى إضافة التبعيات التالية إلى ملف libs.versions.toml. (ننصح باستخدام الإصدار 1.5.1 الذي يتضمّن العديد من إصلاحات الأخطاء المهمة وتحسينات متزامنة للكاميرا).
[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" }بعد ذلك، أضِف ما يلي إلى موارد الاعتمادية في ملف build.gradle.kts الخاص بالوحدة:
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
}هل لديك أسئلة أو تريد التواصل مع فريق CameraX؟ الانضمام إلى مجموعة مناقشة المطوّرين في CameraX أو إرسال تقرير خطأ:
-
أخبار المنتجاتعلى Google Play، نعمل باستمرار على توسيع منصة الاشتراكات لمساعدتك في تعزيز النمو والتكيّف مع نماذج الأعمال الجديدة وتلبية احتياجات المستخدمين أينما كانوا.
Sheenam Mittal • مدّة القراءة: 4 دقائق -
أخبار المنتجاتفي العام الماضي، أصبح بإمكان "استوديو Android" استخدام أي نموذج للذكاء الاصطناعي. واليوم، نتّخذ الخطوة التالية من خلال توفير إمكانية اختيار وكلاء الترميز.
Matthew Warner • مدّة القراءة: 3 دقائق -
أخبار المنتجاتتقدّم Googlebook فئة جديدة من أجهزة الكمبيوتر المحمول المستندة إلى أساس Android المشترك. تجمع أجهزة Chromebook Plus بين سهولة استخدام الأجهزة الجوّالة وقوة أجهزة الكمبيوتر المكتبي، وهي مزوّدة بأجهزة عالية الأداء من شركاء مثل HP وDell وLenovo وAcer وAsus.
Fahd Imtiaz, Loryn Hairston • مدّة القراءة: 4 دقائق
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.