يسجّل نظام الالتقاط عادةً بث الفيديو والبث الصوتي، ويضغطهما، ويجمعهما، ثم يكتب البث الناتج على القرص.
في CameraX، الحلّ لالتقاط الفيديو هو حالة الاستخدام
VideoCapture:
VideoCaptureكما هو موضّح في الشكل 2، يتضمّن التقاط الفيديو في CameraX بعض المكوّنات المعمارية العالية المستوى:
-
SurfaceProviderلمصدر الفيديو -
AudioSourceلمصدر الصوت - برنامجا ترميز لترميز الفيديو والصوت وضغطهما
- مُضاعِف وسائط لمضاعفة البثَّين
- أداة حفظ ملفات لكتابة النتيجة
تستخلص واجهة برمجة التطبيقات VideoCapture API محرّك التسجيل المعقّد وتوفّر للتطبيقات واجهة برمجة تطبيقات أبسط وأسهل بكثير.
نظرة عامة على VideoCapture API
VideoCapture هي حالة استخدام في CameraX تعمل بشكل جيد بمفردها أو عند
دمجها مع حالات استخدام أخرى. تعتمد المجموعات المحدّدة المتوافقة على
إمكانات أجهزة الكاميرا، ولكن Preview وVideoCapture هما
مجموعة حالات استخدام صالحة على جميع الأجهزة.
تتألف واجهة برمجة التطبيقات VideoCapture من العناصر التالية التي تتواصل مع التطبيقات:
VideoCaptureهي فئة حالة الاستخدام الأعلى مستوى. يرتبطVideoCaptureبـLifecycleOwnerمعCameraSelectorوحالات استخدام CameraX الأخرى. لمزيد من المعلومات حول هذه المفاهيم والاستخدامات، يُرجى الاطّلاع على بنية CameraX.Recorderهو تنفيذ لـ VideoOutput مرتبط بشكل وثيق بـ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 API
لدمج حالة استخدام CameraX VideoCapture في تطبيقك،
اتّبِع الخطوات التالية:
- ربط
VideoCapture - إعداد التسجيل وضبطه
- بدء تسجيل وقت التشغيل والتحكّم فيه
توضّح الأقسام التالية ما يمكنك فعله في كل خطوة للحصول على جلسة تسجيل شاملة.
ربط VideoCapture
لربط حالة استخدام VideoCapture، اتّبِع الخطوات التالية:
- أنشِئ عنصر
Recorder. - إنشاء عنصر واحد (
VideoCapture) - الربط بـ
Lifecycle
تتّبع واجهة برمجة التطبيقات VideoCapture في CameraX نمط تصميم أداة الإنشاء. تستخدم التطبيقات Recorder.Builder لإنشاء Recorder. يمكنك أيضًا ضبط درجة دقة الفيديو في "Recorder" من خلال عنصر "QualitySelector".
تتيح واجهة برمجة التطبيقات CameraX Recorder استخدام Qualities المحدّدة مسبقًا التالية
لدرجات دقة الفيديو:
-
Quality.UHDلحجم الفيديو بدقة 4K الفائقة للغاية (2160p) Quality.QHDلحجم فيديو بدقة Quad HD (1440p)، تم تقديمه في CameraX1.7.0-alpha02-
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.QHD, 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.QHD, 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.QHD -> "QHD" 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لالتقاط الصور فيFileDescriptor.FileOutputOptionsلالتقاط الصور فيFile.MediaStoreOutputOptionsلالتقاط الصور فيMediaStore.
تتيح لك جميع أنواع OutputOptions ضبط الحد الأقصى لحجم الملف باستخدام
setFileSizeLimit(). تتعلّق الخيارات الأخرى بنوع الإخراج الفردي، مثل ParcelFileDescriptor لـ FileDescriptorOutputOptions.
يعرض prepareRecording() عنصر PendingRecording، وهو عنصر وسيط يُستخدَم لإنشاء عنصر Recording المقابل. PendingRecording هي فئة عابرة يجب أن تكون غير مرئية في معظم الحالات ونادرًا ما يتم تخزينها مؤقتًا بواسطة التطبيق.
يمكن للتطبيقات ضبط التسجيل بشكل أكبر، مثل:
- فعِّل الصوت باستخدام
withAudioEnabled(). - يمكنك تسجيل أداة معالجة لتلقّي أحداث تسجيل الفيديو
باستخدام
start(Executor, Consumer<VideoRecordEvent>). - يمكنك السماح بتسجيل متواصل أثناء إعادة ربط VideoCapture المرتبط به بكاميرا أخرى، باستخدام
PendingRecording.asPersistentRecording().
لبدء التسجيل، اتصل بالرقم PendingRecording.start(). تحوّل واجهة برمجة التطبيقات CameraX
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_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);
النطاق الديناميكي (فيديو HDR)
تتيح واجهة برمجة التطبيقات CameraX تسجيل فيديوهات 10 بت بنطاق عالي الديناميكية (HDR)، مثل HLG10 أو HDR10 أو HDR10+ أو Dolby Vision، باستخدام DynamicRange.
لاستخدام ميزة تسجيل الفيديو بنطاق عالي الديناميكية، أكمِل الخطوات التالية:
- يمكنك الاستعلام عن النطاقات الديناميكية المتوافقة مع الكاميرا باستخدام
VideoCapabilities.getSupportedDynamicRanges(). - اختياري: في حال ضبط
QualitySelectorمخصّص، تحقَّق من الجودة المتاحة لهذا النطاق الديناميكي باستخدامgetSupportedQualities(DynamicRange). - اضبط "
VideoCapture.Builder" باستخدامsetDynamicRange().
يُفعِّل المثال التالي تسجيل فيديو 10 بت بنطاق عالي الديناميكية (HDR) بتقنية HLG عندما تتيح الكاميرا ذلك:
Kotlin
val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo) val supportedHdrRanges = videoCapabilities.supportedDynamicRanges .filter { it != DynamicRange.SDR } val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .apply { if (supportedHdrRanges.contains(DynamicRange.HLG_10_BIT)) { setDynamicRange(DynamicRange.HLG_10_BIT) } } .build()
Java
VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo); Set<DynamicRange> supportedRanges = videoCapabilities.getSupportedDynamicRanges(); Recorder recorder = new Recorder.Builder().build(); VideoCapture.Builder<Recorder> builder = new VideoCapture.Builder<>(recorder); if (supportedRanges.contains(DynamicRange.HLG_10_BIT)) { builder.setDynamicRange(DynamicRange.HLG_10_BIT); } VideoCapture<Recorder> videoCapture = builder.build();
تثبيت صورة الفيديو
تتيح واجهة CameraX تثبيت صورة الفيديو لتقليل الاهتزاز والتشويش أثناء حمل الجهاز باليد عند تسجيل الفيديو.
لتفعيل ميزة "تثبيت الفيديو"، اتّبِع الخطوات التالية:
- تحقَّق مما إذا كان جهاز الكاميرا يتيح ميزة التثبيت باستخدام
VideoCapabilities.isStabilizationSupported(). - يمكنك تفعيلها على "
VideoCapture.Builder" باستخدامsetVideoStabilizationEnabled(true).
يؤدي المثال التالي إلى تفعيل ميزة التثبيت عندما تكون الكاميرا متوافقة معها:
Kotlin
val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo) val videoCapture = VideoCapture.Builder(recorder) .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported) .build()
Java
VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo); VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(recorder) .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported()) .build();
التحكّم في تسجيل نشط
يمكنك إيقاف 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.
سعة الصوت وحالته في الوقت الفعلي
أثناء التسجيل، توفّر أحداث VideoRecordEvent.Status إحصاءات صوتية في الوقت الفعلي من خلال AudioStats:
- تعرض الدالة
AudioStats.getAudioAmplitude()سعة ذروة الصوت الحالية، وتتراوح قيمتها بين0.0و1.0. يمكنك استخدام هذه القيمة لتشغيل عدّادات واجهة المستخدم أو أدوات عرض الشكل الموجي الصوتي. AudioStats.getAudioState()يشير إلى الحالة الحالية للبث الصوتي، مثلAUDIO_STATE_ACTIVEأوAUDIO_STATE_MUTEDأوAUDIO_STATE_SOURCE_SILENCED.
يقرأ المثال التالي سعة الصوت من حدث حالة:
Kotlin
when (event) { is VideoRecordEvent.Status -> { val audioStats = event.recordingStats.audioStats if (audioStats.hasAudio()) { val amplitude = audioStats.audioAmplitude updateAudioWaveform(amplitude) } } // ... }
Java
if (event instanceof VideoRecordEvent.Status) { VideoRecordEvent.Status status = (VideoRecordEvent.Status) event; AudioStats audioStats = status.getRecordingStats().getAudioStats(); if (audioStats.hasAudio()) { double amplitude = audioStats.getAudioAmplitude(); updateAudioWaveform(amplitude); } }
فيديو عالي السرعة وبالتصوير البطيء
تتيح واجهة CameraX تسجيل الفيديو بسرعة عالية، مثل 120 أو 240 أو 480 لقطة في الثانية، ما يتيح حالتي استخدام مختلفتين:
- فيديو بمعدّل عدد اللقطات في الثانية مرتفع (تصوير بطيء يعالجه المشغّل): تلتقط واجهة CameraX اللقطات وتحفظها بمعدّل عدد اللقطات في الثانية مرتفع (على سبيل المثال، 120 لقطة في الثانية). يتحكّم مشغّل الفيديو في سرعة التشغيل، ما يتيح للمستخدمين التبديل بين السرعة العادية والحركة البطيئة أو إجراء تحليل لكل لقطة على حدة.
- فيديو بالحركة البطيئة جاهز للتشغيل: تعالج واجهة CameraX البث العالي السرعة وتُخرج ملف فيديو عاديًا بمعدل 30 لقطة في الثانية مع طوابع زمنية معدَّلة للقطات. يتم "دمج" تأثير الحركة البطيئة، لذا يتم تشغيل الفيديو بالحركة البطيئة تلقائيًا في أي مشغّل عادي بدون الحاجة إلى مشغّل خاص. على سبيل المثال، إذا تم التقاط فيديو بمعدّل 120 لقطة في الثانية وتشغيله بمعدّل 30 لقطة في الثانية، سيتم إنتاج فيديو بالتصوير البطيء بسرعة 1/4.
التحقّق من إمكانات السرعة العالية
يتطلّب التقاط الفيديو بسرعة عالية توفُّر دعم من الأجهزة وتعريفات CamcorderProfile ذات الصلة من الشركات المصنّعة للأجهزة، مثل CamcorderProfile.QUALITY_HIGH_SPEED_1080P أو QUALITY_HIGH_SPEED_720P.
قبل ضبط التسجيل العالي السرعة، يمكنك الاستعلام عن الإمكانات العالية السرعة باستخدام
Recorder.getHighSpeedVideoCapabilities(CameraInfo):
Kotlin
val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo) if (highSpeedCapabilities == null) { // Camera does not support high-speed video capture return } val supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR)
Java
VideoCapabilities highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo); if (highSpeedCapabilities == null) { // Camera does not support high-speed video capture return; } List<Quality> supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR);
ضبط HighSpeedVideoSessionConfig
لاستخدام ميزة "الالتقاط العالي السرعة"، ادمج حالات استخدام VideoCapture وPreview
في HighSpeedVideoSessionConfig. لضبط الجلسة،
أكمِل الخطوات التالية:
- أنشئ حالة استخدام
VideoCaptureوحالة استخدامPreview. - ابدأ
HighSpeedVideoSessionConfig.Builderباستخدام حالة الاستخدامVideoCaptureوأرفِقPreview. - يمكنك الاستعلام عن نطاقات عدد اللقطات في الثانية المتوافقة باستخدام
CameraInfo.getSupportedFrameRateRanges(SessionConfig)وضبط النطاق المحدّد. - يمكنك الاختيار بين فيديو بمعدّل لقطات مرتفع أو فيديو بالحركة البطيئة جاهز للتشغيل:
- لإنشاء فيديو بمعدّل لقطات مرتفع، اترك
setSlowMotionEnabled(false)(الإعداد التلقائي). - لإنشاء فيديو بالحركة البطيئة جاهز للتشغيل، استخدِم
setSlowMotionEnabled(true).
- لإنشاء فيديو بمعدّل لقطات مرتفع، اترك
- اربط إعدادات الجلسة باستخدام
cameraProvider.bindToLifecycle().
يضبط المثال التالي جلسة حركة بطيئة جاهزة للتشغيل ويربطها:
Kotlin
val preview = Preview.Builder().build() val recorder = Recorder.Builder() .setQualitySelector(QualitySelector.from(supportedQualities.first())) .build() val videoCapture = VideoCapture.withOutput(recorder) // Build HighSpeedVideoSessionConfig val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture) .setPreview(preview) // Enable automatic slow-motion playback at 30 fps .setSlowMotionEnabled(true) // Query and set a supported high-speed frame rate range (such as 120 or 240 fps). // The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier. val supportedFpsRanges = cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build()) sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.first()) val sessionConfig = sessionConfigBuilder.build() // Bind session config to lifecycle cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, sessionConfig )
Java
Preview preview = new Preview.Builder().build(); Recorder recorder = new Recorder.Builder() .setQualitySelector(QualitySelector.from(supportedQualities.get(0))) .build(); VideoCapture<Recorder> videoCapture = VideoCapture.withOutput(recorder); HighSpeedVideoSessionConfig.Builder sessionConfigBuilder = new HighSpeedVideoSessionConfig.Builder(videoCapture) .setPreview(preview) .setSlowMotionEnabled(true); // The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier. Set<Range<Integer>> supportedFpsRanges = cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build()); sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.iterator().next()); HighSpeedVideoSessionConfig sessionConfig = sessionConfigBuilder.build(); cameraProvider.bindToLifecycle( lifecycleOwner, CameraSelector.DEFAULT_BACK_CAMERA, sessionConfig );
يمكنك أيضًا استخدام لغة Kotlin DSL، التي تم تقديمها في الإصدار 1.7.0-alpha02 من CameraX، لضبط جلسات عالية السرعة بإيجاز:
val sessionConfig = highSpeedVideoSessionConfig(videoCapture) {
this.preview = preview
isSlowMotionEnabled = true
frameRateRange = supportedFpsRanges.first()
}
cameraProvider.bindToLifecycle(
lifecycleOwner,
CameraSelector.DEFAULT_BACK_CAMERA,
sessionConfig
)
تسجيل فيديو عالي السرعة أو بالحركة البطيئة
بعد ربط HighSpeedVideoSessionConfig، ابدأ التسجيل باستخدام
VideoCapture بالطريقة نفسها التي تستخدمها في تسجيلات الفيديو العادية:
Kotlin
val recording = videoCapture.output .prepareRecording(context, mediaStoreOutput) .withAudioEnabled() .start(ContextCompat.getMainExecutor(context)) { event -> when (event) { is VideoRecordEvent.Start -> Log.d(TAG, "Recording started") is VideoRecordEvent.Finalize -> { if (!event.hasError()) { Log.d(TAG, "Video saved: ${event.outputResults.outputUri}") } } } }
Java
Recording recording = videoCapture.getOutput() .prepareRecording(context, mediaStoreOutput) .withAudioEnabled() .start(ContextCompat.getMainExecutor(context), event -> { if (event instanceof VideoRecordEvent.Start) { Log.d(TAG, "Recording started"); } else if (event instanceof VideoRecordEvent.Finalize) { VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) event; if (!finalize.hasError()) { Log.d(TAG, "Video saved: " + finalize.getOutputResults().getOutputUri()); } } });
مراجع إضافية
لمزيد من المعلومات حول CameraX، يمكنك الاطّلاع على المراجع الإضافية التالية:
- الدرس التطبيقي حول الترميز: بدء استخدام CameraX
- نموذج تطبيق CameraX الرسمي
- قائمة أحدث واجهات برمجة التطبيقات لتسجيل الفيديو في CameraX
- ملاحظات إصدار CameraX
- الرمز المصدر لـ CameraX
- التقاط الصور بسرعة عالية وتسجيل الفيديو بالحركة البطيئة باستخدام الإصدار 1.5 من CameraX