یک سیستم ضبط به طور کلی جریان های ویدئویی و صوتی را ضبط می کند، آنها را فشرده می کند، دو جریان را به هم متصل می کند، سپس جریان حاصل را روی دیسک می نویسد.

در CameraX، راه حل برای فیلم برداری، استفاده از VideoCapture است:

VideoCapture استفاده میکند.همانطور که در شکل 2 نشان داده شده است، فیلمبرداری CameraX شامل چند جزء معماری سطح بالا است:
-
SurfaceProviderبرای منبع ویدیو. -
AudioSourceبرای منبع صوتی. - دو رمزگذار برای رمزگذاری و فشرده سازی ویدئو/صوت.
- مخزن رسانه ای برای مخلوط کردن دو جریان.
- ذخیرهکننده فایل برای نوشتن نتیجه.
VideoCapture API موتور پیچیده تصویربرداری را خلاصه می کند و برنامه های کاربردی را با API بسیار ساده تر و ساده تر ارائه می دهد.
نمای کلی VideoCapture API
VideoCapture یک کیس استفاده CameraX است که به تنهایی یا زمانی که با موارد استفاده دیگر ترکیب می شود، به خوبی کار می کند. ترکیبهای خاص پشتیبانی شده به قابلیتهای سختافزار دوربین بستگی دارد، اما Preview و VideoCapture یک ترکیب مورد استفاده معتبر در همه دستگاهها هستند.
VideoCapture API از اشیاء زیر تشکیل شده است که با برنامه ها ارتباط برقرار می کنند:
-
VideoCaptureکلاس کاربری سطح بالایی است.VideoCaptureبا یکCameraSelectorو سایر موارد استفاده CameraX بهLifecycleOwnerمتصل می شود. برای اطلاعات بیشتر در مورد این مفاهیم و کاربردها، به معماری CameraX مراجعه کنید. -
Recorderپیاده سازی VideoOutput است که به شدت باVideoCaptureهمراه است.Recorderبرای انجام فیلمبرداری و ضبط صدا استفاده می شود. یک برنامه ازRecorderضبط ایجاد می کند . - یک
PendingRecordingیک ضبط را پیکربندی می کند و گزینه هایی مانند فعال کردن صدا و تنظیم شنونده رویداد را ارائه می دهد. برای ایجادPendingRecordingباید از یکRecorderاستفاده کنید. یکPendingRecordingچیزی را ضبط نمی کند. - A
Recordingضبط واقعی را انجام می دهد. برای ایجاد یکRecordingباید از یکPendingRecordingاستفاده کنید.
شکل 3 روابط بین این اشیاء را نشان می دهد:

افسانه:
- با
QualitySelectorیکRecorderایجاد کنید. -
Recorderبا یکی ازOutputOptionsپیکربندی کنید. - در صورت نیاز صدا را با
withAudioEnabled()فعال کنید. - برای شروع ضبط، با یک شنونده
VideoRecordEventstart()بگیرید. - از
pause()/resume()/stop()درRecordingبرای کنترل ضبط استفاده کنید. - به
VideoRecordEventsدر شنونده رویداد خود پاسخ دهید.
فهرست دقیق API در current.txt داخل کد منبع موجود است.
با استفاده از VideoCapture API
برای ادغام کیس استفاده CameraX VideoCapture در برنامه خود، موارد زیر را انجام دهید:
- Bind
VideoCapture - ضبط را آماده و پیکربندی کنید.
- ضبط زمان اجرا را شروع و کنترل کنید.
بخشهای زیر به تشریح کارهایی که میتوانید در هر مرحله برای دریافت یک جلسه ضبط سرتاسر انجام دهید، میپردازد.
Bind VideoCapture
برای اتصال کیس استفاده VideoCapure ، موارد زیر را انجام دهید:
- یک شی
Recorderایجاد کنید. - شی
VideoCaptureایجاد کنید. - به یک
Lifecycleمتصل شوید.
CameraX VideoCapture API از الگوی طراحی سازنده پیروی می کند. برنامه ها از Recorder.Builder برای ایجاد یک Recorder استفاده می کنند. همچنین میتوانید وضوح تصویر را برای Recorder از طریق یک شی QualitySelector پیکربندی کنید.
CameraX Recorder از Qualities از پیش تعریف شده زیر برای وضوح تصویر پشتیبانی می کند:
-
Quality.UHDبرای اندازه ویدیوی 4K ultra HD (2160p) -
Quality.FHDبرای اندازه ویدیوی فول اچ دی (1080p) -
Quality.HDبرای اندازه ویدیوی HD (720p) -
Quality.SDبرای اندازه ویدیوی SD (480p)
توجه داشته باشید که CameraX همچنین میتواند رزولوشنهای دیگری را در صورت مجوز توسط برنامه انتخاب کند.
اندازه دقیق ویدیوی هر انتخاب به دوربین و قابلیت های رمزگذار بستگی دارد. برای اطلاعات بیشتر، به مستندات CamcorderProfile مراجعه کنید.
برنامه ها می توانند وضوح تصویر را با ایجاد یک QualitySelector پیکربندی کنند. می توانید با استفاده از یکی از روش های زیر یک QualitySelector ایجاد کنید:
با استفاده از
fromOrderedList()چند رزولوشن ترجیحی ارائه دهید، و یک استراتژی بازگشتی برای استفاده در صورتی که هیچ یک از وضوحهای ترجیحی پشتیبانی نمیشود، اضافه کنید.CameraX میتواند بهترین تطابق بازگشتی را بر اساس قابلیت دوربین انتخابی انتخاب کند، برای جزئیات بیشتر به
FallbackStrategy specificationQualitySelectorمراجعه کنید. برای مثال، کد زیر بالاترین رزولوشن پشتیبانی شده را برای ضبط درخواست میکند، و اگر هیچ یک از وضوحهای درخواست پشتیبانی نمیشوند، به 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و شروع فیلمبرداری استفاده کنید.
هنگامی که تابع start() را فراخوانی می کنید، Recorder یک شی Recording برمی گرداند. برنامه شما می تواند از این شیء 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() را ببینید.
کاتلین
val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build() useCases.add(videoCapture);
جاوا
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()برای بی صدا کردن یا لغو صدای ضبط فعلی.
توجه داشته باشید که میتوانید برای پایان دادن به یک Recording بدون توجه به اینکه ضبط در حالت ضبط موقت یا فعال است stop() را فراخوانی کنید.
اگر یک EventListener با PendingRecording.start() ثبت کرده باشید، Recording با استفاده از VideoRecordEvent ارتباط برقرار می کند.
-
VideoRecordEvent.EVENT_TYPE_STATUSبرای ضبط آماری مانند اندازه فایل فعلی و بازه زمانی ثبت شده استفاده می شود. -
VideoRecordEvent.EVENT_TYPE_FINALIZEبرای نتیجه ضبط استفاده می شود و شامل اطلاعاتی مانند URI فایل نهایی به همراه هرگونه خطای مرتبط است.
هنگامی که برنامه شما یک EVENT_TYPE_FINALIZE دریافت کرد که نشان دهنده یک جلسه ضبط موفقیت آمیز است، سپس می توانید از مکان مشخص شده در OutputOptions به ویدیوی ضبط شده دسترسی داشته باشید.
منابع اضافی
برای کسب اطلاعات بیشتر در مورد CameraX، به منابع اضافی زیر مراجعه کنید:
- شروع کار با CameraX Codelab
- برنامه رسمی CameraX نمونه
- آخرین لیست API CameraX Video Capture
- یادداشت های انتشار CameraX
- کد منبع CameraX