โดยทั่วไปแล้ว ระบบจับภาพจะบันทึกสตรีมวิดีโอและเสียงแล้วบีบอัด ปรับสตรีมทั้งสองรายการ จากนั้นเขียนสตรีมผลลัพธ์ไปยังดิสก์
ใน CameraX โซลูชันสำหรับการจับภาพวิดีโอคือ
VideoCapture
กรณีการใช้งาน:
VideoCaptureดังแสดงในรูปที่ 2 การจับภาพวิดีโอจาก CameraX จะรวมภาพระดับสูง ส่วนประกอบทางสถาปัตยกรรม
SurfaceProviderสำหรับแหล่งที่มาของวิดีโอAudioSourceสำหรับแหล่งที่มาของเสียง- โปรแกรมเปลี่ยนไฟล์ 2 โปรแกรมที่ใช้เข้ารหัสและบีบอัดวิดีโอ/เสียง
- คนมักสื่อผสมสตรีมทั้ง 2 แบบ
- ไฟล์รักษาไฟล์เพื่อเขียนผลลัพธ์ออกมา
VideoCapture API จะตัดเครื่องมือจับภาพที่ซับซ้อนและให้ ด้วย API ที่ใช้งานง่ายและเรียบง่ายมากๆ
ภาพรวม VideoCapture API
VideoCapture เป็นกรณีการใช้งานของ CameraX ที่ทำงานได้ดีทั้งในตัวแอปเองหรือเมื่อ
รวมกับกรณีการใช้งานอื่นๆ ชุดค่าผสมที่รองรับเฉพาะขึ้นอยู่กับ
ความสามารถของฮาร์ดแวร์กล้อง แต่ Preview และ VideoCapture
Use Case ที่ถูกต้องร่วมกันในอุปกรณ์ทั้งหมด
VideoCapture API ประกอบด้วยออบเจ็กต์ต่อไปนี้ที่สื่อสาร ด้วยแอปพลิเคชัน
VideoCaptureคือ Use Case ระดับบนสุดVideoCaptureเชื่อมโยงกับLifecycleOwnerที่มีCameraSelectorและ CameraX อื่นๆ Use Case สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแนวคิดและการใช้งานเหล่านี้ โปรดดู สถาปัตยกรรม CameraXRecorderคือ การใช้งาน VideoOutput ที่เชื่อมกับVideoCaptureอย่างใกล้ชิดRecorderจะใช้ในการบันทึกวิดีโอและเสียง CANNOT TRANSLATE แอปพลิเคชันสร้างการบันทึกจากRecorderPendingRecordingกำหนดค่าการบันทึก โดยมอบตัวเลือกต่างๆ เช่น เปิดใช้เสียงและการตั้งค่า Listener เหตุการณ์ คุณต้องใช้Recorderเพื่อสร้างPendingRecordingPendingRecordingจะไม่บันทึกข้อมูลใดๆRecordingจะดำเนินการ บันทึกจริง คุณต้องใช้PendingRecordingเพื่อสร้างRecording
รูปที่ 3 แสดงความสัมพันธ์ระหว่างวัตถุเหล่านี้
คำอธิบาย:
- สร้าง
Recorderด้วยQualitySelector - กำหนดค่า
Recorderด้วยหนึ่งในOutputOptions - เปิดใช้เสียงกับ
withAudioEnabled()หากจำเป็น - โทร
start()กับVideoRecordEventListener เพื่อเริ่มการบันทึก - ใช้
pause()/resume()/stop()ในRecordingเพื่อควบคุมการบันทึก - ตอบกลับ
VideoRecordEventsใน Listener เหตุการณ์
รายการ API โดยละเอียดอยู่ใน current.txt ในซอร์สโค้ด
การใช้ VideoCapture API
วิธีผสานรวมกรณีการใช้งาน VideoCapture ของ CameraX ในแอปของคุณ
ให้ทำดังนี้
- เชื่อมโยง
VideoCapture - เตรียมและกำหนดค่าการบันทึก
- เริ่มต้นและควบคุมการบันทึกรันไทม์
ส่วนต่อไปนี้จะอธิบายถึงสิ่งที่คุณทำได้ในแต่ละขั้นตอน จากต้นทางถึงปลายทาง
เชื่อมโยง VideoCapture
ในการเชื่อมโยงกรณีการใช้งาน VideoCapure ให้ทำดังนี้
- สร้างออบเจ็กต์
Recorder - สร้างออบเจ็กต์
VideoCapture - เชื่อมโยงกับ
Lifecycle
CameraX VideoCapture API เป็นไปตามรูปแบบการออกแบบของเครื่องมือสร้าง การสมัครงาน
ใช้ Recorder.Builder เพื่อสร้าง Recorder นอกจากนี้ คุณยังกำหนดค่า
ความละเอียดของวิดีโอสำหรับ Recorder ผ่านออบเจ็กต์ QualitySelector
CameraX Recorder รองรับ Qualities ที่กำหนดไว้ล่วงหน้าต่อไปนี้
สำหรับความละเอียดของวิดีโอ:
Quality.UHDสำหรับขนาดวิดีโอ 4K Ultra HD (2160p)Quality.FHDสำหรับวิดีโอขนาด Full HD (1080p)Quality.HDสำหรับขนาดวิดีโอ HD (720p)Quality.SDสำหรับขนาดวิดีโอ 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()เพื่อลงทะเบียนVideoRecordEventListener ของคุณ และเริ่มการบันทึกวิดีโอ
Recorder จะแสดงผลออบเจ็กต์ Recording เมื่อคุณเรียกใช้ฟังก์ชัน start()
แอปพลิเคชันของคุณสามารถใช้ออบเจ็กต์ Recording นี้เพื่อสิ้นสุดการดำเนินการ
เพื่อบันทึกหรือดำเนินการอื่นๆ เช่น หยุดชั่วคราวหรือกลับมาทำงานอีกครั้ง
Recorder รองรับออบเจ็กต์ Recording ครั้งละ 1 รายการ คุณสามารถเริ่ม
การบันทึกใหม่เมื่อคุณโทรหา Recording.stop() หรือ
Recording.close() ในออบเจ็กต์ Recording ก่อนหน้า
มาดูรายละเอียดเพิ่มเติมของขั้นตอนเหล่านี้กัน ประการแรก แอปพลิเคชันจะกำหนดค่า
OutputOptions สำหรับโปรแกรมอัดเสียงกับ Recorder.prepareRecording()
Recorder รองรับ OutputOptions ในประเภทต่อไปนี้
FileDescriptorOutputOptionsเพื่อเก็บภาพไปยังFileDescriptorFileOutputOptionsสำหรับการจับภาพไปยังFileMediaStoreOutputOptionsเพื่อเก็บภาพไปยังMediaStore
OutputOptions ทุกประเภทช่วยให้คุณตั้งค่าขนาดไฟล์สูงสุดด้วย
setFileSizeLimit() ตัวเลือกอื่นๆ มีไว้สำหรับเอาต์พุตแต่ละรายการโดยเฉพาะ
เช่น ParcelFileDescriptor สำหรับ FileDescriptorOutputOptions
prepareRecording() แสดงผลออบเจ็กต์ PendingRecording ซึ่งเป็น
ออบเจ็กต์สื่อกลางที่ใช้เพื่อสร้าง
ออบเจ็กต์ Recording รายการ PendingRecording เป็นคลาสชั่วคราวที่ควรจะเป็น
มักจะมองไม่เห็นในกรณีส่วนใหญ่ และมักจะถูกแคชไว้ในแอปน้อย
แอปพลิเคชันอาจกำหนดค่าการบันทึกเพิ่มเติมได้ เช่น
- เปิดใช้เสียงกับ
withAudioEnabled() - ลงทะเบียน Listener เพื่อรับเหตุการณ์การบันทึกวิดีโอ
ด้วย
start(Executor, Consumer<VideoRecordEvent>) - อนุญาตให้มีการบันทึกอย่างต่อเนื่องในขณะที่วิดีโอจับภาพที่แนบอยู่
กลับไปที่กล้องตัวอื่นด้วย
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 มีอยู่ 3 แบบ ได้แก่ 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);
ควบคุมไฟล์บันทึกเสียงที่ใช้งานอยู่
คุณสามารถหยุดชั่วคราว เล่นต่อ และหยุด 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 ได้ในแหล่งข้อมูลเพิ่มเติมต่อไปนี้
- การเริ่มต้นใช้งาน CameraX Codelab
- ตัวอย่างแอป CameraX อย่างเป็นทางการ
- รายการ API การจับภาพวิดีโอจาก CameraX ล่าสุด
- บันทึกประจำรุ่นของ CameraX
- ซอร์สโค้ด CameraX