Computer >> คอมพิวเตอร์ >  >> ระบบ >> Android

Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ

เราทุกคนใช้กล้องในโทรศัพท์ของเราและเราใช้มันอย่างดีที่สุด มีแม้กระทั่งแอปพลิเคชั่นบางตัวที่รวมกล้องไว้เป็นคุณสมบัติ

ด้านหนึ่งมีวิธีมาตรฐานในการโต้ตอบกับกล้อง ในทางกลับกัน มีวิธีปรับแต่งการโต้ตอบกับกล้องของคุณ ความแตกต่างนี้เป็นสิ่งสำคัญที่จะทำให้ และนั่นคือที่มาของ Camera2

Camera2 คืออะไร

แม้ว่าจะมีให้บริการตั้งแต่ API ระดับ 21 แต่ Camera2 API จะต้องเป็นหนึ่งในส่วนที่ซับซ้อนมากขึ้นของนักพัฒนาสถาปัตยกรรมที่ต้องรับมือ

API นี้และรุ่นก่อนถูกนำมาใช้เพื่อให้นักพัฒนาสามารถควบคุมพลังของการโต้ตอบกับกล้องภายในแอปพลิเคชันของตนได้

คล้ายกับวิธีการโต้ตอบกับไมโครโฟนหรือระดับเสียงของอุปกรณ์ Camera2 API ให้เครื่องมือในการโต้ตอบกับกล้องของอุปกรณ์

โดยทั่วไป หากคุณต้องการใช้ Camera2 API อาจเป็นมากกว่าการถ่ายภาพหรือบันทึกวิดีโอ ทั้งนี้เนื่องจาก API ช่วยให้คุณมีการควบคุมเชิงลึกของกล้องโดยเปิดเผยคลาสต่างๆ ที่จะต้องกำหนดค่าสำหรับแต่ละอุปกรณ์

แม้ว่าคุณจะเคยใช้งานกล้องมาก่อนแล้วก็ตาม การเปลี่ยนแปลงครั้งใหญ่จาก API ของกล้องแบบเดิมคือการเปลี่ยนแปลงครั้งใหญ่ ที่คุณอาจลืมทุกสิ่งที่คุณรู้ได้เช่นกัน

มีแหล่งข้อมูลมากมายที่พยายามแสดงวิธีใช้ API นี้โดยตรง แต่บางส่วนอาจล้าสมัยและบางส่วนไม่ได้นำเสนอภาพรวม

ดังนั้น แทนที่จะพยายามกรอกส่วนที่หายไปด้วยตัวเอง บทความนี้ (หวังว่า) จะเป็นแหล่งรวมของคุณสำหรับการโต้ตอบกับ Camera2 API

เคสการใช้งาน Camera2

ก่อนที่เราจะลงลึกในสิ่งใดๆ สิ่งสำคัญคือต้องเข้าใจว่า หากคุณต้องการใช้กล้องเพื่อถ่ายภาพหรือบันทึกวิดีโอเท่านั้น คุณไม่จำเป็นต้องกังวลกับ Camera2 API

เหตุผลหลักในการใช้ Camera2 API คือหากแอปพลิเคชันของคุณต้องการการโต้ตอบแบบกำหนดเองกับกล้องหรือฟังก์ชันการทำงานของกล้อง

หากคุณสนใจที่จะทำอย่างแรกแทนที่จะเป็นอย่างหลัง เราขอแนะนำให้คุณไปที่เอกสารประกอบต่อไปนี้จาก Google:

  1. ถ่ายรูป
  2. จับภาพวิดีโอ

คุณจะพบขั้นตอนที่จำเป็นทั้งหมดเพื่อถ่ายภาพและวิดีโอที่ยอดเยี่ยมด้วยกล้องของคุณ แต่ในบทความนี้จะเน้นไปที่วิธีใช้ Camera2 เป็นหลัก

ตอนนี้ มีบางสิ่งที่เราต้องเพิ่มลงในไฟล์ Manifest:

สิทธิ์ของกล้อง:

<uses-permission android:name="android.permission.CAMERA" />

คุณสมบัติกล้อง:

<uses-feature android:name="android.hardware.camera" />

คุณจะต้องจัดการกับการตรวจสอบว่าได้รับอนุญาตจากกล้องหรือไม่ แต่เนื่องจากหัวข้อนี้ได้รับการกล่าวถึงอย่างกว้างขวาง เราจะไม่จัดการกับสิ่งนั้นในบทความนี้

วิธีการตั้งค่าคอมโพเนนต์ Camera2 API

Camera2 API แนะนำอินเทอร์เฟซและคลาสใหม่มากมาย มาแยกย่อยกันเพื่อให้เราเข้าใจวิธีใช้ได้ดีขึ้น

Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ
ดูส่วนประกอบเหล่านั้นทั้งหมด

ก่อนอื่น เราจะเริ่มด้วย TextureView

ส่วนประกอบ Camera2 TextureView

TextureView เป็นองค์ประกอบ UI ที่คุณใช้เพื่อแสดงสตรีมเนื้อหา (คิดว่าเป็นวิดีโอ) เราจำเป็นต้องใช้ TextureView เพื่อแสดงฟีดจากกล้อง ไม่ว่าจะเป็นภาพตัวอย่างหรือก่อนถ่ายภาพ/วิดีโอ

คุณสมบัติสองประการที่สำคัญต่อการใช้งานเกี่ยวกับ TextureView ได้แก่:

  • ฟิลด์ SurfaceTexture
  • อินเทอร์เฟซ SurfaceTextureListener

ที่แรกคือตำแหน่งที่เนื้อหาจะแสดง และส่วนที่สองมีการโทรกลับสี่ครั้ง:

  1. onSurfaceTextureAvailable
  2. onSurfaceTextureSizeChanged
  3. ปรับปรุงพื้นผิวพื้นผิว
  4. พื้นผิวที่ถูกทำลาย
private val surfaceTextureListener = object : TextureView.SurfaceTextureListener {
        override fun onSurfaceTextureAvailable(texture: SurfaceTexture, width: Int, height: Int) {

        }
        override fun onSurfaceTextureSizeChanged(texture: SurfaceTexture, width: Int, height: Int) {
        
        }
        
        override fun onSurfaceTextureDestroyed(texture: SurfaceTexture) {
           
        }
        override fun onSurfaceTextureUpdated(texture: SurfaceTexture) {
          
        }
}

การโทรกลับครั้งแรกมีความสำคัญเมื่อใช้กล้อง เนื่องจากเราต้องการรับการแจ้งเตือนเมื่อ SurfaceTexture พร้อมใช้งาน เพื่อให้เราสามารถเริ่มแสดงฟีดได้

โปรดทราบว่าเมื่อแนบ TextureView กับหน้าต่างแล้วจะใช้งานได้

การโต้ตอบกับกล้องเปลี่ยนไปตั้งแต่ API ก่อนหน้า ตอนนี้ เรามี CameraManager นี่คือบริการระบบที่ช่วยให้เราสามารถโต้ตอบกับวัตถุ CameraDevice

วิธีการที่คุณต้องการให้ความสนใจเป็นพิเศษคือ:

  • กล้องเปิด
  • getCameraCharacteristics
  • getCameraIdList

หลังจากที่เรารู้ว่า TextureView พร้อมใช้งานและพร้อมแล้ว เราจำเป็นต้องเรียก openCamera เพื่อเปิดการเชื่อมต่อกับกล้อง วิธีนี้ใช้สามอาร์กิวเมนต์:

  1. CameraId - สตริง
  2. CameraDevice.StateCallback
  3. ตัวจัดการ

อาร์กิวเมนต์ CameraId หมายถึงกล้องตัวใดที่เราต้องการเชื่อมต่อ ในโทรศัพท์ของคุณ ส่วนใหญ่จะมีกล้องสองตัวคือด้านหน้าและด้านหลัง แต่ละคนมีรหัสเฉพาะของตัวเอง โดยปกติแล้วจะเป็นศูนย์หรือหนึ่ง

เราจะรับ ID กล้องได้อย่างไร? เราใช้วิธี getCamerasIdList ของ CameraManager มันจะส่งคืนอาร์เรย์ของประเภทสตริงของรหัสกล้องทั้งหมดที่ระบุจากอุปกรณ์

val cameraManager: CameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraIds: Array<String> = cameraManager.cameraIdList
var cameraId: String = ""
for (id in cameraIds) {
    val cameraCharacteristics = cameraManager.getCameraCharacteristics(id)
    //If we want to choose the rear facing camera instead of the front facing one
    if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) 
      continue
    }
    
    val previewSize = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!.getOutputSizes(ImageFormat.JPEG).maxByOrNull { it.height * it.width }!!
    val imageReader = ImageReader.newInstance(previewSize.width, previewSize.height, ImageFormat.JPEG, 1)
    imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler)
    cameraId = id
}

อาร์กิวเมนต์ต่อไปคือการเรียกกลับไปยังสถานะของกล้องหลังจากที่เราพยายามเปิดมัน หากคุณลองคิดดู การดำเนินการนี้จะมีผลลัพธ์ได้หลายอย่างเท่านั้น:

  • เปิดกล้องได้สำเร็จ
  • กล้องหลุด
  • เกิดข้อผิดพลาดบางอย่าง

และนั่นคือสิ่งที่คุณจะพบใน CameraDevice.StateCallback:

 private val cameraStateCallback = object : CameraDevice.StateCallback() {
        override fun onOpened(camera: CameraDevice) {
           
        }

        override fun onDisconnected(cameraDevice: CameraDevice) {
           
        }

        override fun onError(cameraDevice: CameraDevice, error: Int) {
            val errorMsg = when(error) {
                ERROR_CAMERA_DEVICE -> "Fatal (device)"
                ERROR_CAMERA_DISABLED -> "Device policy"
                ERROR_CAMERA_IN_USE -> "Camera in use"
                ERROR_CAMERA_SERVICE -> "Fatal (service)"
                ERROR_MAX_CAMERAS_IN_USE -> "Maximum cameras in use"
                else -> "Unknown"
            }
            Log.e(TAG, "Error when trying to connect camera $errorMsg")
        }
    }

อาร์กิวเมนต์ที่สามเกี่ยวข้องกับตำแหน่งที่งานนี้จะเกิดขึ้น เนื่องจากเราไม่ต้องการครอบครองเธรดหลัก การทำงานนี้ในเบื้องหลังจึงดีกว่า

นั่นเป็นเหตุผลที่เราต้องส่ง Handler ไปให้ จะเป็นการดีที่จะให้อินสแตนซ์ตัวจัดการนี้สร้างอินสแตนซ์ด้วยเธรดที่เราเลือก เพื่อให้เราสามารถมอบหมายงานได้

private lateinit var backgroundHandlerThread: HandlerThread
private lateinit var backgroundHandler: Handler

 private fun startBackgroundThread() {
    backgroundHandlerThread = HandlerThread("CameraVideoThread")
    backgroundHandlerThread.start()
    backgroundHandler = Handler(
        backgroundHandlerThread.looper)
}

private fun stopBackgroundThread() {
    backgroundHandlerThread.quitSafely()
    backgroundHandlerThread.join()
}

ด้วยทุกสิ่งที่เราทำ ตอนนี้เราสามารถเรียก openCamera:

cameraManager.openCamera(cameraId, cameraStateCallback,backgroundHandler)

จากนั้นใน onOpened เราสามารถเริ่มจัดการกับตรรกะในการนำเสนอฟีดกล้องแก่ผู้ใช้ผ่าน TextureView ได้

Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ
รูปภาพโดย Markus Spiske บน Unsplash

วิธีการแสดงตัวอย่างฟีด

เรามีกล้อง (cameraDevice) และ TextureView ของเราเพื่อแสดงฟีด แต่เราจำเป็นต้องเชื่อมต่อเข้าด้วยกันเพื่อให้เราสามารถแสดงตัวอย่างฟีดได้

ในการทำเช่นนั้น เราจะใช้คุณสมบัติ SurfaceTexture ของ TextureView และเราจะสร้าง CaptureRequest

val surfaceTexture : SurfaceTexture? = textureView.surfaceTexture // 1

val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) //2
val previewSize = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
  .getOutputSizes(ImageFormat.JPEG).maxByOrNull { it.height * it.width }!!

surfaceTexture?.setDefaultBufferSize(previewSize.width, previewSize.height) //3

val previewSurface: Surface = Surface(surfaceTexture)

captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) //4
captureRequestBuilder.addTarget(previewSurface) //5

cameraDevice.createCaptureSession(listOf(previewSurface, imageReader.surface), captureStateCallback, null) //6
กำลังสร้างภาพตัวอย่าง

ในโค้ดด้านบน ขั้นแรกเราจะได้ SurfaceTexture จาก TextureView ของเรา จากนั้นเราใช้วัตถุ cameraCharacteristics เพื่อรับรายการขนาดเอาต์พุตทั้งหมด เพื่อให้ได้ขนาดที่ต้องการ เราตั้งค่าสำหรับ SurfaceTexture

ต่อไป เราสร้าง captureRequest ที่เราส่งใน TEMPLATE_PREVIEW . เราเพิ่มพื้นผิวอินพุตของเราไปยัง captureRequest

สุดท้าย เราเริ่มการดักจับเซสชันด้วยพื้นผิวอินพุตและเอาต์พุต, captureStateCallback และส่งผ่านค่า null สำหรับตัวจัดการ

แล้ว captureStateCallback นี้คืออะไร? หากคุณจำไดอะแกรมตั้งแต่ต้นบทความนี้ แสดงว่าเป็นส่วนหนึ่งของ CameraCaptureSession ที่เรากำลังจะเริ่มต้น ออบเจ็กต์นี้ติดตามความคืบหน้าของ captureRequest ด้วยการเรียกกลับดังต่อไปนี้:

  • onConfigured
  • onConfigureFailed
private val captureStateCallback = object : CameraCaptureSession.StateCallback() {
        override fun onConfigureFailed(session: CameraCaptureSession) {
            
        }
        override fun onConfigured(session: CameraCaptureSession) {
         
        }
}

เมื่อ cameraCaptureSession ได้รับการกำหนดค่าเรียบร้อยแล้ว เราตั้งค่าคำขอซ้ำสำหรับเซสชันเพื่อให้เราสามารถแสดงตัวอย่างได้อย่างต่อเนื่อง

ในการทำเช่นนั้น เราใช้วัตถุเซสชันที่เราได้รับในการเรียกกลับ:

 session.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler)

คุณจะรู้จักวัตถุ captureRequestBuilder ที่เราสร้างไว้ก่อนหน้านี้ว่าเป็นอาร์กิวเมนต์แรกสำหรับวิธีนี้ เรากำหนดวิธีการสร้างเพื่อให้พารามิเตอร์สุดท้ายที่ส่งผ่านเข้ามาคือ CaptureRequest

อาร์กิวเมนต์ที่สองคือ Listener CameraCaptureSession.captureCallback แต่เนื่องจากเราไม่ต้องการทำอะไรกับภาพที่ถ่าย (เนื่องจากนี่เป็นการแสดงตัวอย่าง) เราจึงส่งผ่านเป็นโมฆะ

อาร์กิวเมนต์ที่สามคือตัวจัดการ และที่นี่เราใช้ backgroundHandler ของเราเอง นี่คือสาเหตุที่เราส่งค่า null ในส่วนก่อนหน้า เนื่องจากคำขอซ้ำจะทำงานบนเธรดพื้นหลัง

Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ
รูปภาพโดย Dicky Jiang บน Unsplash

วิธีถ่ายภาพ

การแสดงตัวอย่างกล้องแบบสดนั้นยอดเยี่ยม แต่ผู้ใช้ส่วนใหญ่อาจต้องการทำอะไรกับมัน ตรรกะบางอย่างที่เราจะเขียนเพื่อถ่ายภาพจะคล้ายกับที่เราทำในส่วนที่แล้ว

  1. เราจะสร้าง captureRequest
  2. เราจะใช้ ImageReader และผู้ฟังเพื่อรวบรวมภาพที่ถ่าย
  3. การใช้ cameraCaptureSession ของเรา เราจะเรียกใช้วิธีการจับภาพ
val orientations : SparseIntArray = SparseIntArray(4).apply {
    append(Surface.ROTATION_0, 0)
    append(Surface.ROTATION_90, 90)
    append(Surface.ROTATION_180, 180)
    append(Surface.ROTATION_270, 270)
}

val captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
captureRequestBuilder.addTarget(imageReader.surface)

val rotation = windowManager.defaultDisplay.rotation
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, orientations.get(rotation))
cameraCaptureSession.capture(captureRequestBuilder.build(), captureCallback, null)
ครั้งนี้เรากำลังสร้างคำขอจับภาพด้วย TEMPLATE_STILL_CAPTURE

แต่ ImageReader นี้คืออะไร? ImageReader ให้การเข้าถึงข้อมูลภาพที่แสดงผลบนพื้นผิว ในกรณีของเรา มันคือพื้นผิวของ TextureView

หากคุณดูข้อมูลโค้ดจากส่วนก่อนหน้า คุณจะสังเกตเห็นว่าเราได้กำหนด ImageReader ไว้ที่นั่นแล้ว

val cameraManager: CameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraIds: Array<String> = cameraManager.cameraIdList
var cameraId: String = ""
for (id in cameraIds) {
    val cameraCharacteristics = cameraManager.getCameraCharacteristics(id)
    //If we want to choose the rear facing camera instead of the front facing one
    if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) 
      continue
    }
    
    val previewSize = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!.getOutputSizes(ImageFormat.JPEG).maxByOrNull { it.height * it.width }!!
    val imageReader = ImageReader.newInstance(previewSize.width, previewSize.height, ImageFormat.JPEG, 1)
    imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler)
    cameraId = id
}
ประกาศบรรทัดที่ 12 – 14

ดังที่คุณเห็นด้านบน เราสร้าง ImageReader โดยส่งผ่านความกว้างและความสูง รูปแบบรูปภาพที่เราต้องการให้รูปภาพของเราอยู่ และจำนวนรูปภาพที่สามารถจับภาพได้

คุณสมบัติที่คลาส ImageReader มีคือฟังที่เรียกว่า onImageAvailableListener ผู้ฟังรายนี้จะถูกทริกเกอร์เมื่อมีการถ่ายภาพ (เนื่องจากเราผ่านพื้นผิวเป็นแหล่งเอาต์พุตสำหรับคำขอจับภาพของเรา)

val onImageAvailableListener = object: ImageReader.OnImageAvailableListener{
        override fun onImageAvailable(reader: ImageReader) {
            val image: Image = reader.acquireLatestImage()
        }
    }

⚠️ อย่าลืมปิดรูปภาพหลังจากประมวลผลแล้ว มิฉะนั้น คุณจะไม่สามารถถ่ายภาพอื่นได้อีก

Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ
รูปภาพโดย Jakob Owens บน Unsplash

วิธีการบันทึกวิดีโอ

ในการบันทึกวิดีโอ เราต้องโต้ตอบกับวัตถุใหม่ที่เรียกว่า MediaRecorder วัตถุตัวบันทึกสื่อมีหน้าที่ในการบันทึกเสียงและวิดีโอ และเราจะใช้มันทำอย่างนั้น

ก่อนที่เราจะทำอะไร เราต้องตั้งค่าเครื่องบันทึกสื่อก่อน มีการกำหนดค่าต่างๆ ให้จัดการและต้องอยู่ในลำดับที่ถูกต้อง มิฉะนั้นจะมีข้อยกเว้น .

ด้านล่างนี้คือตัวอย่างการกำหนดค่าต่างๆ ที่จะช่วยให้เราสามารถจับภาพวิดีโอ (ไม่มีเสียง)

fun setupMediaRecorder(width: Int, height: Int) {
  val mediaRecorder: MediaRecorder = MediaRecorder()
  mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
  mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
  mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
  mediaRecorder.setVideoSize(videoSize.width, videoSize.height)
  mediaRecorder.setVideoFrameRate(30)
  mediaRecorder.setOutputFile(PATH_TO_FILE)
  mediaRecorder.setVideoEncodingBitRate(10_000_000)
  mediaRecorder.prepare()
}
ลำดับของเซ็ตเตอร์มีความสำคัญ

ให้ความสนใจกับ setOutputFile วิธีตามที่คาดไว้เส้นทางไปยังไฟล์ที่จะเก็บวิดีโอของเรา เมื่อสิ้นสุดการตั้งค่าการกำหนดค่าทั้งหมดเหล่านี้ เราจำเป็นต้องเรียกการจัดเตรียม

โปรดทราบว่า mediaRecorder มีเมธอด start ด้วยเช่นกัน และเราต้องเรียก prepare ก่อนเรียกใช้

หลังจากตั้งค่า mediaRecoder แล้ว เราจำเป็นต้องสร้างคำขอจับภาพและเซสชันการจับภาพ

fun startRecording() {
        val surfaceTexture : SurfaceTexture? = textureView.surfaceTexture
        surfaceTexture?.setDefaultBufferSize(previewSize.width, previewSize.height)
        val previewSurface: Surface = Surface(surfaceTexture)
        val recordingSurface = mediaRecorder.surface
        captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
        captureRequestBuilder.addTarget(previewSurface)
        captureRequestBuilder.addTarget(recordingSurface)

        cameraDevice.createCaptureSession(listOf(previewSurface, recordingSurface), captureStateVideoCallback, backgroundHandler)
    }

เช่นเดียวกับการตั้งค่าการแสดงตัวอย่างหรือการถ่ายภาพ เราต้องกำหนดพื้นผิวอินพุตและเอาต์พุตของเรา

ที่นี่เรากำลังสร้างวัตถุ Surface จากพื้นผิวพื้นผิวของ TextureView และนำพื้นผิวจากเครื่องบันทึกสื่อ เรากำลังผ่านใน TEMPLATE_RECORD ค่าเมื่อสร้างคำขอดักจับ

captureStateVideoCallback ของเราเป็นประเภทเดียวกับที่เราใช้สำหรับภาพนิ่ง แต่ในการโทรกลับ onConfigured เราเรียกวิธีการเริ่มต้นของเครื่องบันทึกสื่อ

val captureStateVideoCallback = object : CameraCaptureSession.StateCallback() {
      override fun onConfigureFailed(session: CameraCaptureSession) {
         
      }
      
      override fun onConfigured(session: CameraCaptureSession) {
          session.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler)
          mediaRecorder.start()
      }
  }
ในที่นี้ เรายังตั้งค่าคำขอที่เกิดซ้ำเนื่องจากเราต้องการจับภาพวิดีโอต่อเนื่อง

ตอนนี้เรากำลังบันทึกวิดีโอ แต่เราจะหยุดบันทึกได้อย่างไร? สำหรับสิ่งนั้น เราจะใช้วิธีการหยุดและรีเซ็ตบนวัตถุ mediaRecorder:

mediaRecorder.stop()
mediaRecorder.reset()

บทสรุป

นั่นเป็นจำนวนมากในการประมวลผล ดังนั้นหากคุณทำสำเร็จแล้ว ยินดีด้วย! ไม่มีทางแก้ไขได้ เพียงแค่ทำให้มือสกปรกด้วยโค้ด คุณก็จะเริ่มเข้าใจว่าทุกอย่างเชื่อมต่อกันอย่างไร

คุณได้รับการสนับสนุนมากกว่าที่จะดูโค้ดทั้งหมดที่แสดงในบทความนี้ด้านล่าง :

MediumArticles/Camrea2API at master · TomerPacific/MediumArticlesที่เก็บโค้ดที่เกี่ยวข้องกับบทความ Medium ต่างๆ ที่ฉันเขียน - MediumArticles/Camrea2API at master · TomerPacific/MediumArticles Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ TomerPacificGitHub Android Camera2 – วิธีใช้ Camera2 API เพื่อถ่ายภาพและวิดีโอ

โปรดทราบว่านี่เป็นเพียงส่วนเล็กสุดของภูเขาน้ำแข็งเมื่อพูดถึง Camera2 API มีหลายสิ่งที่คุณทำได้ เช่น ถ่ายวิดีโอสโลว์โมชั่น สลับระหว่างกล้องหน้าและกล้องหลัง ควบคุมโฟกัส และอื่นๆ อีกมากมาย