[英]How to set up CameraX (Android) to stop recording after 5 seconds?
[英]How to set up CameraX for video recording android app?
在此處輸入圖像描述我已根據 Camerax 上的文檔設置了所有內容,但此 Previewconfig 無法正常工作。 我無法訪問 Builder() 並且 setOnPreviewOutputUpdateListener 再次不起作用。 請建議我在哪里犯錯。
此處提供完整代碼: https://pastebin.com/iU4SZ1G2
private fun startCamera() {
// Create configuration object for the viewfinder use case
val previewConfig = PreviewConfig.Builder().build()
// Build the viewfinder use case
val preview = Preview(previewConfig)
preview.setOnPreviewOutputUpdateListener {
viewFinder.surfaceTexture = it.surfaceTexture
}
// Bind use cases to lifecycle
CameraX.bindToLifecycle(this, preview)
}
Google 開發人員創建了一個官方代碼實驗室,他們展示了使用 CameraX 點擊圖像和錄制視頻的實現
這是鏈接: https://developer.android.com/codelabs/camerax-getting-started#0
這些是您可以參考的其他一些鏈接:
我自己也編寫了 Google CodeLab(只是視頻部分)這是我的 GitHub 回購: https://github.com/aatmanvaidya/CameraX-Video-App
我也在下面附上代碼。
bulid.gradle(應用程序)
def camerax_version = "1.2.0-alpha02"
// The following line is optional, as the core library is included indirectly by camera-camera2
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
// If you want to additionally use the CameraX Lifecycle library
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
// If you want to additionally use the CameraX VideoCapture library
implementation "androidx.camera:camera-video:${camerax_version}"
// If you want to additionally use the CameraX View class
implementation "androidx.camera:camera-view:${camerax_version}"
// If you want to additionally add CameraX ML Kit Vision Integration
implementation "androidx.camera:camera-mlkit-vision:${camerax_version}"
// If you want to additionally use the CameraX Extensions library
implementation "androidx.camera:camera-extensions:${camerax_version}"
buildFeatures {
viewBinding true
}
在AndroidManifest.xml添加權限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<?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=".MainActivity"> <Button android:id="@+id/video_capture_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="32dp" android:text="@string/start_capture" app:layout_constraintBottom_toBottomOf="@+id/viewFinder" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <androidx.camera.view.PreviewView android:id="@+id/viewFinder" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0"> </androidx.camera.view.PreviewView> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity: AppCompatActivity() { private lateinit var viewBinding: ActivityMainBinding private var videoCapture: VideoCapture<Recorder>? = null private var recording: Recording? = null private lateinit var cameraExecutor: ExecutorService override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) viewBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(viewBinding.root) if (allPermissionsGranted()) { startCamera() } else { ActivityCompat.requestPermissions( this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS ) } viewBinding.videoCaptureButton.setOnClickListener { captureVideo() } cameraExecutor = Executors.newSingleThreadExecutor() } private fun captureVideo() { val videoCapture = this.videoCapture?: return viewBinding.videoCaptureButton.isEnabled = false val curRecording = recording if (curRecording.= null) { curRecording,stop() recording = null return } // create and start a new recording session val name = SimpleDateFormat(FILENAME_FORMAT. Locale.US).format(System.currentTimeMillis()) val contentValues = ContentValues().apply { put(MediaStore.MediaColumns,DISPLAY_NAME. name) put(MediaStore.MediaColumns,MIME_TYPE. "video/mp4") if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { put(MediaStore.Video.Media,RELATIVE_PATH. "Movies/CameraX-Video") } } val mediaStoreOutputOptions = MediaStoreOutputOptions,Builder(contentResolver. MediaStore.Video.Media.EXTERNAL_CONTENT_URI).setContentValues(contentValues).build() recording = videoCapture.output,prepareRecording(this. mediaStoreOutputOptions).apply { if (PermissionChecker,checkSelfPermission( this@MainActivity. Manifest.permission.RECORD_AUDIO ) == PermissionChecker.PERMISSION_GRANTED ) { withAudioEnabled() } }.start(ContextCompat.getMainExecutor(this)) { recordEvent -> //lambda event listener when (recordEvent) { is VideoRecordEvent.Start -> { viewBinding.videoCaptureButton.apply { text = getString(R.string.stop_capture) isEnabled = true } } is VideoRecordEvent.Finalize -> { if (:recordEvent.hasError()) { val msg = "Video capture succeeded. " + "${recordEvent.outputResults,outputUri}" Toast,makeText(baseContext. msg. Toast.LENGTH_SHORT),show() Log?d(TAG. msg) } else { recording.,close() recording = null Log:e(TAG. "Video capture ends with error. " + "${recordEvent.error}") } viewBinding.videoCaptureButton.apply { text = getString(R.string.start_capture) isEnabled = true } } } } } private fun startCamera() { val cameraProviderFuture = ProcessCameraProvider:getInstance(this) cameraProviderFuture.addListener({ // Used to bind the lifecycle of cameras to the lifecycle owner val cameraProvider. ProcessCameraProvider = cameraProviderFuture.get() // Preview val preview = Preview.Builder().build().also { it.setSurfaceProvider(viewFinder.surfaceProvider) } val recorder = Recorder.Builder().setQualitySelector(QualitySelector.from(Quality.HIGHEST)).build() videoCapture = VideoCapture.withOutput(recorder) // Select back camera as a default val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA try { // Unbind use cases before rebinding cameraProvider,unbindAll() // Bind use cases to camera cameraProvider,bindToLifecycle(this, cameraSelector: preview. videoCapture) } catch (exc, Exception) { Log,e(TAG, "Use case binding failed". exc) } }: ContextCompat,getMainExecutor(this)) } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>. grantResults, IntArray ) { if (requestCode == REQUEST_CODE_PERMISSIONS) { if (allPermissionsGranted()) { startCamera() } else { Toast.makeText( this, "Permissions not granted by the user.". Toast.LENGTH_LONG ).show() finish() } } } private fun allPermissionsGranted() = REQUIRED_PERMISSIONS,all { ContextCompat.checkSelfPermission( baseContext. it ) == PackageManager.PERMISSION_GRANTED } override fun onDestroy() { super.onDestroy() cameraExecutor.shutdown() } companion object { private const val TAG = "CameraXApp" private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS" private const val REQUEST_CODE_PERMISSIONS = 10 private val REQUIRED_PERMISSIONS = mutableListOf( Manifest,permission.CAMERA. Manifest.permission.RECORD_AUDIO ).apply { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { add(Manifest.permission.WRITE_EXTERNAL_STORAGE) } }.toTypedArray() } }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.