【问题标题】:Does CameraX support to record video with Kotlin?CameraX 是否支持使用 Kotlin 录制视频?
【发布时间】:2019-10-21 08:53:46
【问题描述】:

我已阅读 https://developer.android.com/training/camerax 上的 CameraX 概述。

我想录视频,CameraX支持录视频吗?

顺便说一句,Can I record video with CameraX (Android Jetpack)? 中的代码不适用于最新的camerax_version = "1.0.0-alpha06"

【问题讨论】:

    标签: android android-camerax


    【解决方案1】:

    【讨论】:

    • 谢谢,我可以用 GitHub 克隆项目吗?
    • 还有,我找不到布局文件activity_camera_xmain
    • 在这里您可以找到使用 cameraX 库进行视频录制的解决方案:stackoverflow.com/questions/56054647/…
    • 致 Abhishek Chaniyara:谢谢!但 stackoverflow.com/questions/56054647/… 不适用于 camerax_version = "1.0.0-alpha06"
    • 您可以创建一个activity_camera_xmain布局文件并添加其中使用的控件。
    【解决方案2】:

    是的,CameraX 也支持录制视频。

    我最近创建了演示。 请检查以下代码。

    Java 文件

    private const val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
    private val tag = MainActivity::class.java.simpleName
    
    
    
    @SuppressLint("RestrictedApi, ClickableViewAccessibility")
    class VideoCaptureActivity : AppCompatActivity(), LifecycleOwner {
    
        private lateinit var viewFinder: TextureView
        private lateinit var captureButton: ImageButton
        private lateinit var videoCapture: VideoCapture
        private var lensFacing = CameraX.LensFacing.BACK
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_video_capture)
    
            viewFinder = findViewById(R.id.view_finder)
            captureButton = findViewById(R.id.capture_button)
    
            // Request camera permissions
            if (allPermissionsGranted()) {
                viewFinder.post { startCamera() }
            } else {
                ActivityCompat.requestPermissions(
                    this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
                )
            }
    
            val file = File(
                externalMediaDirs.first(),"${System.currentTimeMillis()}.mp4"
            )
    
            captureButton.setOnTouchListener { _, event ->
                if (event.action == MotionEvent.ACTION_DOWN) {
                    captureButton.setBackgroundColor(Color.GREEN)
                    videoCapture.startRecording(file, object : VideoCapture.OnVideoSavedListener {
                        override fun onVideoSaved(file: File?) {
                            Log.i(tag, "Video File : $file")
                        }
    
                        override fun onError(
                            useCaseError: VideoCapture.UseCaseError?,
                            message: String?,
                            cause: Throwable?
                        ) {
                            Log.i(tag, "Video Error: $message")
                        }
                    })
    
                } else if (event.action == MotionEvent.ACTION_UP) {
                    captureButton.setBackgroundColor(Color.RED)
                    videoCapture.stopRecording()
                    Log.i(tag, "Video File stopped")
                }
                false
            }
        }
    
        override fun onRequestPermissionsResult(
            requestCode: Int, permissions: Array<String>, grantResults: IntArray
        ) {
            if (requestCode == REQUEST_CODE_PERMISSIONS) {
                if (allPermissionsGranted()) {
                    viewFinder.post { startCamera() }
                } else {
                    Toast.makeText(this,"Permissions not granted by the user.",Toast.LENGTH_SHORT).show()
                    finish()
                }
            }
        }
    
        private fun allPermissionsGranted(): Boolean {
            for (permission in REQUIRED_PERMISSIONS) {
                if (ContextCompat.checkSelfPermission(
                        this, permission
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    return false
                }
            }
            return true
        }
    
        private fun startCamera() {
            // Create configuration object for the viewfinder use case
            val previewConfig = PreviewConfig.Builder().apply {
                setLensFacing(lensFacing)
            }.build()
            // Build the viewfinder use case
            val preview = Preview(previewConfig)
    
            // Create a configuration object for the video use case
            val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
                setTargetRotation(viewFinder.display.rotation)
                setLensFacing(lensFacing)
            }.build()
            videoCapture = VideoCapture(videoCaptureConfig)
    
            preview.setOnPreviewOutputUpdateListener {
    
                val parent = viewFinder.parent as ViewGroup
                parent.removeView(viewFinder)
                viewFinder.surfaceTexture = it.surfaceTexture
                parent.addView(viewFinder, 0)
    
            }
    
            // Bind use cases to lifecycle
            CameraX.bindToLifecycle(this, preview, videoCapture)
        }
    
        public final fun changeCamera(view : View) : Unit{
            lensFacing = if (CameraX.LensFacing.FRONT == lensFacing) {
                CameraX.LensFacing.BACK
            } else {
                CameraX.LensFacing.FRONT
            }
            try {
                // Only bind use cases if we can query a camera with this orientation
                CameraX.getCameraWithLensFacing(lensFacing)
    
                // Unbind all use cases and bind them again with the new lens facing configuration
                CameraX.unbindAll()
                startCamera()
            } catch (exc: Exception) {
                // Do nothing
            }
        }
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activities.VideoCaptureActivity">
    
        <TextureView
            android:id="@+id/view_finder"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    
        <ImageButton
            android:id="@+id/capture_button"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="24dp"
            android:background="#F44336"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view_finder"
            app:layout_constraintVertical_bias="0.923"
            app:srcCompat="@android:drawable/ic_menu_camera" />
    
        <ImageButton
            android:id="@+id/switch_button"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:onClick="changeCamera"
            android:layout_marginBottom="24dp"
            android:background="@color/colorPrimary"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.024"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view_finder"
            app:layout_constraintVertical_bias="0.923"
            app:srcCompat="@android:drawable/ic_menu_revert" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    我在gradle下面用过。

    def camerax_version = "1.0.0-alpha03"
    implementation "androidx.camera:camera-core:${camerax_version}"
    implementation "androidx.camera:camera-camera2:${camerax_version}"
    

    【讨论】:

    • 谢谢!但是您的代码在camerax_version = "1.0.0-alpha06" 下无法正常工作
    • @HelloCW 可能在某些方法上有变化,但您可以使用此代码并且确实需要更改。
    猜你喜欢
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多