يسجّل نظام الالتقاط بشكل عام أحداث الفيديو والصوت ويضغطها، ثم يدمج الحدثين، ثم يكتب الحدث الناتج على القرص.
في 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
لدمج حالة استخدام VideoCapture في CameraX في تطبيقك،
اتّبِع الخطوات التالية:
- ربط
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 { it.cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_BACK } // Filter to SDR resolutions supported by both the camera sensor and Recorder // encoder so the UI picker only displays valid options. val supportedQualities = Recorder.getVideoCapabilities(cameraInfo[0]).getSupportedQualities(DynamicRange.SDR) val filteredQualities = arrayListOf (Quality.UHD, Quality.QHD, Quality.FHD, Quality.HD, Quality.SD) .filter { supportedQualities.contains(it) } viewBinding.simpleQualityListView.apply { adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, filteredQualities.map { it.qualityToString() }) setOnItemClickListener { _, _, position, _ -> // QualitySelector is configured at Recorder build time, so selecting // a new resolution requires building a new Recorder instance. val qualitySelector = QualitySelector.from(filteredQualities[position]) val recorder = Recorder.Builder() .setQualitySelector(qualitySelector).build() // ... } } 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() } }كل
Qualityيتم عرضه من خلالVideoCapabilities.getSupportedQualities(منRecorder.getVideoCapabilitiesلـDynamicRange.SDR) يعمل مع حالة استخدام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 لا تكون معكوسة تلقائيًا. باستخدام الإصدار 1.3 من CameraX، أصبح من الممكن الآن عكس تسجيلات الفيديو بحيث تتطابق معاينة الكاميرا الأمامية مع الفيديو المسجّل.
هناك ثلاثة خيارات لـ 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 بت بنطاق عالي الديناميكية بتقنية 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 );
يمكنك أيضًا استخدام لغة DSL في Kotlin، التي تم تقديمها في الإصدار 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