โดยทั่วไปแล้ว ระบบจับภาพจะบันทึกสตรีมวิดีโอและเสียงแล้วบีบอัด ปรับสตรีมทั้งสองรายการ จากนั้นเขียนสตรีมผลลัพธ์ไปยังดิสก์
![แผนภาพระบบบันทึกวิดีโอและเสียง](https://developer.android.com/static/images/training/camera/camerax/conceptual-capturing-system.png?authuser=8&hl=th)
ใน CameraX โซลูชันสำหรับการจับภาพวิดีโอคือ
VideoCapture
กรณีการใช้งาน:
![แผนภาพที่แสดงวิธีที่กล้อง x จัดการกับ
กรณีการใช้งานการจับภาพวิดีโอ](https://developer.android.com/static/images/training/camera/camerax/videocapture-use-case.png?authuser=8&hl=th)
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 แอปพลิเคชันสร้างการบันทึกจากRecorder
PendingRecording
กำหนดค่าการบันทึก โดยมอบตัวเลือกต่างๆ เช่น เปิดใช้เสียงและการตั้งค่า Listener เหตุการณ์ คุณต้องใช้Recorder
เพื่อสร้างPendingRecording
PendingRecording
จะไม่บันทึกข้อมูลใดๆRecording
จะดำเนินการ บันทึกจริง คุณต้องใช้PendingRecording
เพื่อสร้างRecording
รูปที่ 3 แสดงความสัมพันธ์ระหว่างวัตถุเหล่านี้
![แผนภาพแสดงการโต้ตอบที่เกิดขึ้นในวิดีโอ
บันทึก Use Case](https://developer.android.com/static/images/training/camera/camerax/videocapture-roles-interaction.png?authuser=8&hl=th)
คำอธิบาย:
- สร้าง
Recorder
ด้วยQualitySelector
- กำหนดค่า
Recorder
ด้วยหนึ่งในOutputOptions
- เปิดใช้เสียงกับ
withAudioEnabled()
หากจำเป็น - โทร
start()
กับVideoRecordEvent
Listener เพื่อเริ่มการบันทึก - ใช้
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()
เพื่อลงทะเบียนVideoRecordEvent
Listener ของคุณ และเริ่มการบันทึกวิดีโอ
Recorder
จะแสดงผลออบเจ็กต์ Recording
เมื่อคุณเรียกใช้ฟังก์ชัน start()
แอปพลิเคชันของคุณสามารถใช้ออบเจ็กต์ Recording
นี้เพื่อสิ้นสุดการดำเนินการ
เพื่อบันทึกหรือดำเนินการอื่นๆ เช่น หยุดชั่วคราวหรือกลับมาทำงานอีกครั้ง
Recorder
รองรับออบเจ็กต์ Recording
ครั้งละ 1 รายการ คุณสามารถเริ่ม
การบันทึกใหม่เมื่อคุณโทรหา 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()
- ลงทะเบียน 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)); } VideoCaptureR<ecorder >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