我使用以下代码捕获视频。一切都很好,但是在捕获视频之后,registerForActivityResult(ActivityResultContracts.TakeVideo())总是为空。捕获的视频存在于给定的路径中。我能用什么方法解决这个问题?
private fun openCameraForMovie() {
val packageManager = requireContext().packageManager
Intent(MediaStore.ACTION_VIDEO_CAPTURE).also { takeVideoIntent ->
takeVideoIntent.resolveActivity(packageManager)?.also {
startRecording()
}
}
}
private fun startRecording() {
try {
val root = File(
requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
.toString() + "/media/"
)
if (!root.exists()) {
root.mkdir()
}
val videoName = "vid_" + System.currentTimeMillis() + ".mp4"
val sdImageMainDirectory = File(root, videoName)
var fileUri: Uri? = FileProvider.getUriForFile(
requireContext(),
context?.applicationContext?.packageName + ".provider",
sdImageMainDirectory
) ?: return
mViewModel.videoUri.postValue(fileUri)
} catch (ex: Exception) {
Timber.d("startRecording ${ex.localizedMessage}")
}
}此代码始终为空:
private val recordVideoResult =
registerForActivityResult(ActivityResultContracts.TakeVideo()) { it ->
try {
if (it != null) {
Timber.d(">>>> Video Bitmap: $it")
}
} catch (ex: Exception) {
Timber.d(">>>> Video Bitmap: ${ex.localizedMessage}")
}
}发布于 2021-03-14 09:15:33
发生什么事了呢?
保存到提供的content-**
Uri.中的视频的ActivityResultContract返回一个缩略图。**
源TakeVideo文档,强调地雷。
您不需要缩略图(反正这是可选的),您需要指向实际视频的Uri。但是您已经知道了Uri,因为您提供了它作为输入。
这次又是什么?
要做到这一点,需要采取几个步骤:
Uri存储在变量中,并正确处理保存状态,这样应用程序就知道当您从相机应用程序返回时,您一直在录制视频。TakeVideo协议,如果视频捕获成功,它将返回。检查非空预览Bitmap无法使用,因为预览是可选的.它看起来可能是这样的:
private AtomicReference<Uri> recordingUri = new AtomicReference<>();
private ActivityResultLauncher<Uri> recordVideoResult =
registerForActivityResult(new TakeVideo2(), success -> {
final Uri uri = recordingUri.getAndSet(null);
if (success) {
// Do something with the video.
}
});
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
// ...
if (savedInstanceState != null) {
recordingUri.set(savedInstanceState.getParcelable("recordingUri"));
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
// ...
outState.putParcelable("recordingUri", recordingUri.get());
}
private void startRecording() {
final Uri uri = // ...;
recordingUri.set(uri);
recordVideoResult.launch(uri);
}
public static class TakeVideo2 extends ActivityResultContract<Uri, Boolean> {
@CallSuper
@NonNull
@Override
public Intent createIntent(@NonNull Context context, @NonNull Uri input) {
return new Intent(MediaStore.ACTION_VIDEO_CAPTURE)
.putExtra(MediaStore.EXTRA_OUTPUT, input);
}
@Nullable
@Override
public final SynchronousResult<Boolean> getSynchronousResult(@NonNull Context context,
@NonNull Uri input) {
return null;
}
@Override
public final Boolean parseResult(int resultCode, @Nullable Intent intent) {
return resultCode == Activity.RESULT_OK;
}
}https://stackoverflow.com/questions/66621919
复制相似问题