نقدّم لك الإصدار 1.5 من CameraX: تسجيل فيديو فعّال والتقاط صور احترافية
مدّة القراءة: 7 دقائق
يسرّ فريق CameraX الإعلان عن طرح الإصدار 1.5. يركّز هذا التحديث الأخير على توفير إمكانات احترافية في متناول يدك مع تسهيل ضبط جلسة الكاميرا أكثر من أي وقت مضى.
أما بالنسبة إلى تسجيل الفيديو، فيمكن للمستخدمين الآن التقاط فيديوهات مذهلة بالحركة البطيئة أو بعدد لقطات مرتفع في الثانية بسهولة. والأهم من ذلك أنّ واجهة برمجة التطبيقات Feature Group API الجديدة تتيح لك تفعيل مجموعات معقّدة بثقة، مثل فيديو 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 واجهة برمجة التطبيقات Feature Group API التي تلغي الحاجة إلى التخمين بشأن توافق الميزات. استنادًا إلى واجهة برمجة التطبيقات لطلب البحث عن مجموعة الميزات في Android 15، يمكنك الآن تفعيل ميزات متعددة معًا بثقة، ما يضمن جلسة كاميرا مستقرة. تتيح مجموعة الميزات حاليًا ما يلي: النطاق العالي الديناميكية (HLG) و60 لقطة في الثانية وميزة "تثبيت الصورة في المعاينة" و"دقة HDR الفائقة". على سبيل المثال، يمكنك تفعيل ميزات 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
}
}يُرجى الاطّلاع على منشور المدوّنة حول Feature Group لمزيد من المعلومات.
تحسينات إضافية على الفيديو
- تحسينات على الكاميرا المتزامنة: باستخدام الإصدار 1.5.1 من CameraX، يمكنك الآن ربط حالات استخدام Preview وImageCapture وVideoCapture في الوقت نفسه لكل 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 مفهومًا جديدًا في الإصدار 1.5 من CameraX. فهي تتيح مركزية الإعدادات وتبسّط واجهة برمجة التطبيقات بطريقتَين رئيسيتَين:
- لا مزيد من طلبات البيانات اليدوية من
unbind(): واجهات برمجة التطبيقات CameraX تدرك دورة الحياة. سيؤدي ذلك ضمنيًا إلى "إلغاء ربط" حالات الاستخدام عند إتلاف النشاط أوLifecycleOwnerأخرى. ومع ذلك، يتطلّب تعديل حالات الاستخدام أو تبديل الكاميرات استدعاءunbind()أوunbindAll()قبل إعادة الربط. الآن، مع الإصدار 1.5 من CameraX، عند ربطSessionConfigجديد، يحدّث CameraX الجلسة بسلاسة، ما يلغي الحاجة إلى طلبات إلغاء الربط. - التحكّم في عدد اللقطات في الثانية بشكل حتمي: توفّر واجهة برمجة التطبيقات
SessionConfigالجديدة طريقة حتمية لإدارة عدد اللقطات في الثانية. على عكس الطريقة السابقةsetTargetFrameRateالتي كانت مجرد تلميح، تضمن هذه الطريقة الجديدة تطبيق نطاق عدد اللقطات في الثانية المحدّد بعد ضبط الإعدادات بنجاح. لضمان الدقة، يجب الاستعلام عن أعداد اللقطات في الثانية المتوافقة باستخدامCameraInfo.getSupportedFrameRateRanges(SessionConfig). من خلال تمريرSessionConfigالكامل، يمكن لـ CameraX تحديد النطاقات المتوافقة بدقة استنادًا إلى إعدادات البث.
مكتبة Camera-Compose أصبحت مستقرة الآن
ندرك مدى إعجابك بمجموعة أدوات Jetpack Compose، ويسرّنا الإعلان عن أنّ الإصدار 1.5.1 من مكتبة camera-compose أصبح الآن مستقرًا. يتضمّن هذا الإصدار إصلاحات لأخطاء مهمة تتعلّق باستخدام CameraXViewfinder مع ميزات Compose، مثل moveableContentOf وPager، بالإضافة إلى حلّ مشكلة تمديد المعاينة. سنواصل إضافة المزيد من الميزات إلى camera-compose في الإصدارات المستقبلية.
تحسينات على ImageAnalysis وCameraControl
- تعديل قوة المصباح اليدوي: يمكنك التحكّم بدقة في المصباح اليدوي للجهاز باستخدام واجهات برمجة التطبيقات الجديدة. يمكنك الاستعلام عن الحد الأقصى لشدة الإضاءة المتاحة باستخدام CameraInfo.getMaxTorchStrengthLevel() ثم ضبط المستوى المطلوب باستخدام CameraControl.setTorchStrengthLevel().
- إتاحة تنسيق NV21 في
ImageAnalysis: يمكنك الآن طلب تنسيق الصورة NV21 مباشرةً منImageAnalysis، ما يسهّل عملية الدمج مع المكتبات وواجهات برمجة التطبيقات الأخرى. يتم تفعيل هذه الميزة من خلال استدعاءImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).
البدء اليوم
حدِّث تبعياتك إلى الإصدار 1.5 من CameraX اليوم واستكشِف الميزات الجديدة الرائعة. نحن متحمّسون لرؤية ابتكاراتك.
لاستخدام الإصدار 1.5 من CameraX، يُرجى إضافة التبعيات التالية إلى ملف 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 أو أرسِل تقرير خطأ:
-
أخبار المنتجاتبما أنّ Unity تشغّل أكثر من نصف جميع الألعاب على الأجهزة الجوّالة في جميع أنحاء العالم، فإنّ الانطباعات الأولى مهمة. بالنسبة إلى مطوّري الألعاب، تُعدّ تجربة الإعداد السلسة والموثوقة للاعبين ضرورية لتعزيز معدّل الاحتفاظ باللاعبين من اليوم الأول وزيادة تفاعلهم على المدى الطويل.
Michelle Martin • مدّة القراءة: دقيقة واحدة -
أخبار المنتجاتمن خلال تطوير التطبيقات على Android XR، يمكنك تلبية احتياجات المستخدمين في أي وقت، سواء كانوا يبحثون عن تجربة غامرة بالكامل في المنزل أو تجربة سريعة أثناء التنقل، وذلك من خلال مجموعة واسعة من التطبيقات المكانية. في مؤتمر Android Dev Summit، احتفلنا بإنجاز رائع من خلال إطلاق نظارة XREAL AURA.
Amy Zeppenfeld, Vinny DaSilva • مدّة القراءة: 3 دقائق -
أخبار المنتجاتفي عصر الذكاء الاصطناعي، لم يعُد المستخدمون يكتفون بالنقر على التطبيقات، بل يعبّرون عن أهداف عالية المستوى ويتوقّعون من وكلاء الذكاء الاصطناعي، مثل Gemini، إكمال مهام متعددة الخطوات، أحيانًا على تطبيقات متعددة على أجهزتهم.
Jingyu Shi • مدّة القراءة: 4 دقائق
يمكنك الحصول على آخر الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.