我正在实现一个 Android 应用程序,我正在尝试使用 CameraX VideoCapture Api 录制视频,但我遇到了一些错误,我想知道如何解决它们。这是视频录制代码:
private fun recordVideo() {
binding.buttonCapture.setImageResource(R.drawable.baseline_stop_24)
val currentRecording = recording
if (currentRecording != null) {
// A recording is already in progress, stop it
currentRecording.stop()
recording = null
binding.buttonCapture.setImageResource(R.drawable.baseline_camera_24)
return
}
val name: String = SimpleDateFormat(
"yyy-MM-dd-HH-mm-ss-SSS",
Locale.getDefault()
).format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4")
put(MediaStore.MediaColumns.RELATIVE_PATH, "Movies/CameraX-Recorder")
}
val options = MediaStoreOutputOptions.Builder(requireContext().contentResolver, EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
recording = videoCapture?.output?.prepareRecording(requireContext(), options)
?.start(ContextCompat.getMainExecutor(requireContext())) { videoRecordEvent ->
// Handle different recording events
when (videoRecordEvent) {
is VideoRecordEvent.Start -> {
// Handle the start of a new active recording
binding.buttonCapture.setImageResource(R.drawable.baseline_stop_24)
}
is VideoRecordEvent.Pause -> {
// Handle the case where the active recording is paused
}
is VideoRecordEvent.Resume -> {
// Handle the case where the active recording is resumed
}
is VideoRecordEvent.Finalize -> {
val finalizeEvent = videoRecordEvent as VideoRecordEvent.Finalize
// Handle the finalize event for the active recording, checking Finalize.getError()
val error = finalizeEvent.error
if (error != VideoRecordEvent.Finalize.ERROR_NONE) {
// Handle error during recording finalization
Toast.makeText(
requireContext(),
"There was an error during video finalization: ${videoRecordEvent.error}",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
requireContext(),
"The video has been successfully recorded",
Toast.LENGTH_SHORT
).show()
}
binding.buttonCapture.setImageResource(R.drawable.baseline_camera_24)
}
}
// All events, including VideoRecordEvent.Status, contain RecordingStats.
// This can be used to update the UI or track the recording duration.
val recordingStats = videoRecordEvent.recordingStats
}
}
这里有错误,我得到:
执行可运行的 androidx.camera.core.impl.utils.executor.SequentialExecutor$1@3592bcb 时出现异常 java.lang.UnsupportedOperationException:无法直接修改相册 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:221) 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:189) 在 android.content.ContentProviderProxy.insert(ContentProviderNative.java:549) 在 android.content.ContentResolver.insert(ContentResolver.java:2151) 在 android.content.ContentResolver.insert(ContentResolver.java:2113) 在 androidx.camera.video.Recorder$RecordingRecord.lambda$initializeRecording$1(Recorder.java:2847) 在 androidx.camera.video.Recorder$RecordingRecord$$ExternalSyntheticLambda0.get(来源未知:4) 在 androidx.camera.video.Recorder$RecordingRecord.performOneTimeMediaMuxerCreation(Recorder.java:3070) 在 androidx.camera.video.Recorder.setupAndStartMediaMuxer(Recorder.java:1464) 在 androidx.camera.video.Recorder$4.onEncodedData(Recorder.java:1666) 在 androidx.camera.video.internal.encoder.EncoderImpl$MediaCodecCallback.lambda$sendEncodedData$3(EncoderImpl.java:1227) 在 androidx.camera.video.internal.encoder.EncoderImpl$MediaCodecCallback$$ExternalSyntheticLambda10.run(未知来源:4) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$1.run(SequentialExecutor.java:111) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:231) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:173) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 在 java.lang.Thread.run(Thread.java:923) 2023-06-08 09:52:05.099 11359-11577 记录器 E 致命异常:CameraX-camerax_io_0 进程:com.ticanalysis.lagfo_kotlin,PID:11359 java.lang.AssertionError:已创建一次性媒体复用器以记录 RecordingRecord{getOutputOptions=MediaStoreOutputOptions{fileSizeLimit=0,durationLimitMillis=0,location=null,contentResolver=android.app.ContextImpl$ApplicationContentResolver@2a50ef2,collectionUri=content //media/external/audio/albums,contentValues=_display_name=2023-06-08-09-52-04-760 mime_type=video/mp4relative_path=Movies/CameraX-Recorder},getCallbackExecutor=android.os.HandlerExecutor@ c014943,getEventListener = com.ticanalysis.lagfo_kotlin.VideoRecorder$$ExternalSyntheticLambda2@db0cbc0,hasAudioEnabled = false,isPersistent = false,getRecordingId = 1} 在 androidx.camera.video.Recorder$RecordingRecord.performOneTimeMediaMuxerCreation(Recorder.java:3067) 在 androidx.camera.video.Recorder.setupAndStartMediaMuxer(Recorder.java:1464) 在 androidx.camera.video.Recorder$4.onEncodedData(Recorder.java:1666) 在 androidx.camera.video.internal.encoder.EncoderImpl$MediaCodecCallback.lambda$sendEncodedData$3(EncoderImpl.java:1227) 在 androidx.camera.video.internal.encoder.EncoderImpl$MediaCodecCallback$$ExternalSyntheticLambda10.run(未知来源:4) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$1.run(SequentialExecutor.java:111) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:231) 在 androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:173) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 在 java.lang.Thread.run(Thread.java:923)
似乎是权限问题。您的应用程序是否具有
WRITE_EXTERNAL_STORAGE
/requestLegacyExternalStorage
权限?
从日志来看,
java.lang.UnsupportedOperationException: Albums cannot be directly modified
和
collectionUri=content://media/external/audio/albums
看起来你应该使用
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
而不是 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI