يسجّل نظام الالتقاط بشكل عام عمليات بث الفيديو والصوت ويضغطها مزج البثين، ثم كتابة الدفق الناتج إلى القرص.
في CameraX، يكون حل التقاط الفيديو هو
VideoCapture
حالة الاستخدام:
VideoCapture.كما هو موضح في الشكل 2، يتضمن التقاط فيديو CameraX بعض الطبقات المكونات المعمارية:
SurfaceProviderلمصدر الفيديو.AudioSourceلمصدر الصوت.- برنامجا ترميز لترميز الفيديو/الصوت وضغطه
- جهاز وسائط لمزج البث المباشر
- توفير ملفات لكتابة النتيجة
تعمل واجهة برمجة التطبيقات VideoCapture على تجريد محرك الالتقاط المعقد وتوفر ذات واجهة برمجة تطبيقات أبسط ومباشرة.
نظرة عامة حول VideoCapture API
إنّ VideoCapture هي حالة استخدام CameraX تعمل بشكل منفرد أو عندما
إلى جانب حالات استخدام أخرى. تعتمد المجموعات المحددة المعتمدة على
إمكانات جهاز الكاميرا، ولكن Preview وVideoCapture
تركيبة حالة استخدام صالحة على جميع الأجهزة.
تتألف واجهة برمجة التطبيقات VideoCapture من الكائنات التالية التي تتصل مع التطبيقات:
VideoCaptureهو فئة حالة استخدام عالية المستوى. يرتبطVideoCaptureبـLifecycleOwnerمعCameraSelectorوجهاز CameraX آخر حالات الاستخدام. لمزيد من المعلومات عن هذه المفاهيم والاستخدامات، يُرجى الاطّلاع على بنية CameraX.Recorderهي تنفيذ "مخرجات الفيديو" إلى جانبVideoCapture. تُستخدَمRecorderلتسجيل الفيديو والصوت. إنّ ينشئ التطبيق تسجيلات منRecorder.PendingRecordingلإعداد التسجيل، وتوفير خيارات مثل تفعيل الصوت والإعدادات أداة معالجة الحدث. يجب استخدامRecorderلإنشاءPendingRecording. لا تسجِّلPendingRecordingأي بيانات.- ينفذ
Recordingالتسجيل الفعلي. يجب استخدامPendingRecordingلإنشاءRecording.
يوضح الشكل 3 العلاقات بين هذه الكائنات:
وسيلة الإيضاح:
- إنشاء
RecorderباستخدامQualitySelector - ضبط
Recorderباستخدام إحدىOutputOptions - تفعيل الصوت باستخدام
withAudioEnabled()إذا لزم الأمر. - الاتصال بالرقم
start()معVideoRecordEventالمستمع لبدء التسجيل. - استخدام
pause()/resume()/stop()فيRecordingللتحكم في التسجيل. - الرد على
VideoRecordEventsداخل أداة معالجة الحدث.
تتوفر قائمة واجهات برمجة التطبيقات التفصيلية في ملف current.txt داخل رمز المصدر.
استخدام واجهة برمجة تطبيقات VideoCapture
لدمج حالة استخدام CameraX VideoCapture في تطبيقك، يُرجى اتّباع الخطوات التالية:
قم بما يلي:
- ربط
VideoCapture. - إعداد التسجيل وضبطه
- بدء التسجيل في بيئة التشغيل والتحكّم فيه
توضّح الأقسام التالية ما يمكنك فعله في كل خطوة للحصول على جلسة تسجيل شاملة.
ربط تسجيل الفيديو
لربط حالة الاستخدام VideoCapure، يمكنك اتّباع الخطوات التالية:
- أنشئ عنصر
Recorder. - إنشاء عنصر
VideoCapture - الربط بـ
Lifecycle
تتبع واجهة برمجة تطبيقات CameraX VideoCapture نمط تصميم أداة الإنشاء. الطلبات
استخدام Recorder.Builder لإنشاء Recorder يمكنك أيضًا ضبط
درجة دقة الفيديو لـ Recorder من خلال كائن QualitySelector.
يتوافق CameraX Recorder مع ميزات Qualities المحددة مسبقًا التالية.
لدرجات دقة الفيديو:
Quality.UHDلفيديو بدقة فائقة بتنسيق 4K (2160p)Quality.FHDلمشاهدة الفيديو بالحجم الكامل بدقة عالية (1080p)Quality.HDلحجم الفيديو بدقة عالية (720p)Quality.SDلحجم الفيديو بدقة عادية (480p)
ويُرجى العِلم أنّه يمكن لتطبيق CameraX أيضًا اختيار درجات دقة أخرى إذا كان التطبيق يسمح بذلك.
يعتمد حجم الفيديو الدقيق لكل اختيار على الكاميرا وبرنامج الترميز
والإمكانات. لمزيد من المعلومات، راجع وثائق
CamcorderProfile
يمكن للتطبيقات ضبط درجة الدقة من خلال إنشاء
QualitySelector
يمكنك إنشاء QualitySelector باستخدام إحدى الطرق التالية:
تقديم بعض درجات الدقة المفضّلة باستخدام
fromOrderedList()تضمين استراتيجية احتياطية لاستخدامها في حالة عدم وجود ودرجات الدقة المفضلة،يمكن لـ CameraX تحديد أفضل مطابقة احتياطية بناءً على عدسة الكاميرا المحددة يمكنك الرجوع إلى نظام
FallbackStrategy specificationالخاص بـQualitySelectorلمزيد من التفاصيل. على سبيل المثال، يطلب الرمز التالي أعلى مستوى دعم للتسجيل، وإذا لم يمكن دعم أي من حلول الطلبات، السماح لـ CameraX باختيار الدقة الأقرب إلى درجة دقة Quality.SD:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))يمكنك الاستعلام عن إمكانات الكاميرا أولاً، ثم الاختيار من بين درجات الدقة باستخدام
QualitySelector::from():val cameraInfo = cameraProvider.availableCameraInfos.filter { Camera2CameraInfo .from(it) .getCameraCharacteristic(CameraCharacteristics.LENS\_FACING) == CameraMetadata.LENS_FACING_BACK } val supportedQualities = QualitySelector.getSupportedQualities(cameraInfo[0]) val filteredQualities = arrayListOf (Quality.UHD, Quality.FHD, Quality.HD, Quality.SD) .filter { supportedQualities.contains(it) } // Use a simple ListView with the id of simple_quality_list_view viewBinding.simpleQualityListView.apply { adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, filteredQualities.map { it.qualityToString() }) // Set up the user interaction to manually show or hide the system UI. setOnItemClickListener { _, _, position, _ -> // Inside View.OnClickListener, // convert Quality.* constant to QualitySelector val qualitySelector = QualitySelector.from(filteredQualities[position]) // Create a new Recorder/VideoCapture for the new quality // and bind to lifecycle val recorder = Recorder.Builder() .setQualitySelector(qualitySelector).build() // ... } } // A helper function to translate Quality to a string fun Quality.qualityToString() : String { return when (this) { Quality.UHD -> "UHD" Quality.FHD -> "FHD" Quality.HD -> "HD" Quality.SD -> "SD" else -> throw IllegalArgumentException() } }لاحظ أن الإمكانية التي تم إرجاعها من
QualitySelector.getSupportedQualities()أن يعمل مع حالة الاستخدامVideoCaptureأو الجمع بين حالة استخدامVideoCaptureوPreview. عند الربط مع حالة الاستخدام "ImageCapture" أو "ImageAnalysis"، CameraX قد لا ينجح في الربط عندما لا تكون المجموعة المطلوبة متاحة على الكاميرا المطلوبة.
بعد الحصول على QualitySelector، يمكن للتطبيق إنشاء
كائن VideoCapture ونفِّذ عملية الربط. لاحظ أن هذا الربط
كما هو الحال مع حالات الاستخدام الأخرى:
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
val videoCapture = VideoCapture.withOutput(recorder)
try {
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
يُرجى العِلم أنّ bindToLifecycle() تعرض الكائن Camera. راجِع هذا الدليل للحصول على مزيد من المعلومات حول التحكّم في إخراج الكاميرا، مثل التكبير أو التصغير والتعرض للضوء.
ويختار Recorder التنسيق الأنسب للنظام. الأكثر
برنامج ترميز الفيديو الشائع
H.264 AVC) مع
تنسيق الحاوية
MPEG-4:
إعداد التسجيل وإنشاؤه
من Recorder، يمكن للتطبيق إنشاء عناصر تسجيل
إجراء التقاط الفيديو والصوت. تنشئ التطبيقات تسجيلات من خلال إجراء
ما يلي:
- ضبط
OutputOptionsباستخدامprepareRecording() - (اختياري) فعِّل التسجيل الصوتي.
- استخدام
start()لتسجيلVideoRecordEventالمستمع والبدء في التقاط الفيديو.
تعرض Recorder الكائن Recording عند استدعاء الدالة start().
يمكن لتطبيقك استخدام عنصر Recording هذا لإكمال العملية.
اتخاذ إجراءات أخرى أو تنفيذها، مثل الإيقاف المؤقت أو الاستئناف.
يتيح Recorder استخدام عنصر Recording واحد في كل مرة. يمكنك بدء
تسجيلاً جديدًا بعد الاتصال بـ Recording.stop() أو
Recording.close() في الكائن Recording السابق.
لنلقِ نظرة على هذه الخطوات بمزيد من التفصيل. أولاً، يقوم التطبيق بتهيئة
OutputOptions لمسجّلة ذكية مع Recorder.prepareRecording().
تتوافق Recorder مع الأنواع التالية من OutputOptions:
FileDescriptorOutputOptionsلالتقاط صورةFileDescriptorFileOutputOptionsلتسجيل فيديو فيFileMediaStoreOutputOptionsلالتقاط صورةMediaStore
تتيح لك جميع أنواع OutputOptions ضبط حد أقصى لحجم الملف باستخدام
setFileSizeLimit() أمّا الخيارات الأخرى، تقتصر على النتائج الفردية
النوع، مثل ParcelFileDescriptor للإشارة إلى FileDescriptorOutputOptions.
تعرض الدالة prepareRecording() الكائن PendingRecording،
كائن وسيط يستخدم لإنشاء
كائن Recording. PendingRecording هي فئة عابرة يجب
تكون غير مرئية في معظم الحالات ونادرًا ما يتم تخزينها مؤقتًا بواسطة التطبيق.
يمكن للتطبيقات ضبط المزيد من إعدادات التسجيل، مثل:
- تفعيل الصوت مع
withAudioEnabled() - تسجيل أداة استماع لتلقّي أحداث تسجيلات الفيديو
مع
start(Executor, Consumer<VideoRecordEvent>). - السماح بتسجيل التسجيل باستمرار أثناء إرفاقه بـ VideoCapture
بالعودة إلى كاميرا أخرى، باستخدام
PendingRecording.asPersistentRecording()
لبدء التسجيل، اتصل برقم PendingRecording.start(). تقوم كاميرا X بتحويل
PendingRecording إلى Recording، ويضيف طلب التسجيل إلى قائمة الانتظار،
وتُرجع كائن Recording الذي تم إنشاؤه حديثًا إلى التطبيق.
بعد بدء التسجيل على جهاز الكاميرا المقابل، ترسل CameraX
حدث واحد (VideoRecordEvent.EVENT_TYPE_START).
يوضح المثال التالي كيفية تسجيل فيديو وصوت في
ملف MediaStore:
// Create MediaStoreOutputOptions for our recorder
val name = "CameraX-recording-" +
SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis()) + ".mp4"
val contentValues = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, name)
}
val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
// 2. Configure Recorder and Start recording to the mediaStoreOutput.
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
أثناء انعكاس معاينة الكاميرا على الكاميرا الأمامية تلقائيًا، التي تسجّلها VideoCapture، لا يتم مزامنتها على الجهاز وفي السحابة الإلكترونية بشكل تلقائي. أما مع الإصدار CameraX 1.3، فتتميز من الممكن الآن إجراء نسخ مطابق لتسجيلات الفيديو حتى تبرز معاينة الكاميرا الأمامية تطابق فيديو مسجّل.
هناك ثلاثة خيارات لـ MirrorMode: MIRROR_mode_OFF وMIRROR_mode_ON وMIRROR_mode_ON
MIRROR_mode_ON_FRONT_ONLY. للمحاذاة مع
معاينة الكاميرا، تنصح Google باستخدام MIROR_mode_ON_FRONT_ONLY، وهو ما يعني
الذي/التي
ميزة "المزامنة على الجهاز وفي السحابة الإلكترونية" غير مفعّلة للكاميرا الخلفية، ولكن مفعَّلة في الكاميرا الأمامية
والكاميرا. لمزيد من المعلومات حول MirrorMode، يمكنك الاطلاع على
MirrorMode constants
يعرض مقتطف الرمز هذا طريقة طلب
VideoCapture.Builder.setMirrorMode() باستخدام MIRROR_MODE_ON_FRONT_ONLY بالنسبة
للحصول على مزيد من المعلومات، يُرجى الاطّلاع على setMirrorMode().
Kotlin
val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build() useCases.add(videoCapture);
Java
Recorder.Builder builder = new Recorder.Builder(); if (mVideoQuality != QUALITY_AUTO) { builder.setQualitySelector( QualitySelector.from(mVideoQuality)); } VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(builder.build()) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build(); useCases.add(videoCapture);
التحكّم في تسجيل نشط
يمكنك إيقاف Recording الحالية مؤقتًا واستئنافها وإيقافها بحلول
باستخدام الطرق التالية:
pauseلإيقاف التسجيل النشِط الحالي مؤقتًا.resume()لاستئناف تسجيل نشط تم إيقافه مؤقتًا.stop()لإنهاء التسجيل ومسح أي عناصر تسجيل مرتبطة.mute()لكتم صوت التسجيل الحالي أو إعادته
تجدر الإشارة إلى أنّه يمكنك الاتصال بـ stop() لإنهاء Recording بغض النظر عن ذلك.
لتحديد ما إذا كان التسجيل في حالة إيقاف مؤقت أو نشط.
إذا سجّلت نطاق EventListener من خلال
PendingRecording.start()، تتواصل Recording
باستخدام
VideoRecordEvent
- تُستخدم السمة
VideoRecordEvent.EVENT_TYPE_STATUSلتسجيل إحصاءات مثل بحجم الملف الحالي والفترة الزمنية المسجّلة. - يتم استخدام
VideoRecordEvent.EVENT_TYPE_FINALIZEلنتيجة التسجيل. وتتضمن معلومات مثل عنوان URI للملف النهائي مع أي أخطاء ذات صلة.
وبعد أن يتلقّى تطبيقك رسالة EVENT_TYPE_FINALIZE، تشير إلى نجاح العملية.
جلسة التسجيل، يمكنك الوصول إلى الفيديو الذي تم التقاطه من الموقع
المحددة في OutputOptions.
مصادر إضافية
للتعرف على مزيد من المعلومات حول CameraX، يمكنك الاطلاع على الموارد الإضافية التالية:
- بدء استخدام الدرس التطبيقي حول ترميز الكاميراX
- نموذج تطبيق CameraX الرسمي
- قائمة أحدث واجهة برمجة التطبيقات لـ CameraX Video Capture
- ملاحظات إصدار CameraX
- رمز المصدر CameraX