美文网首页
调用系统相机拍视频并将视频插入相册

调用系统相机拍视频并将视频插入相册

作者: NewNiu | 来源:发表于2021-11-16 11:56 被阅读0次

请求相机功能

如果您应用的基本功能是拍照,请将其在 Google Play 上的显示范围限制在装有相机的设备上。如需声明您的应用依赖于相机,请在清单文件中添加 <uses-feature> 代码:

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

如果您的应用使用相机,但不需要相机也可以正常运作,应将 android:required 设为 false。这样,Google Play 便会允许未装有相机的设备下载您的应用。因此,您必须负责通过调用 hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) 检查相机在运行时的可用性。如果相机不可用,您应停用相机功能。

使用相机应用录制视频

推荐一个比startActivityForResult更方便获取一个Activity的返回结果的方法:

@NonNull
    @Override
    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull ActivityResultContract<I, O> contract,
            @NonNull ActivityResultCallback<O> callback) {
        return registerForActivityResult(contract, mActivityResultRegistry, callback);
    }
请求录制视频

录视频之前需要先生成视频保存位置Uri,方便后面使用
生成Uri方法如下:

    /**
     * 获取拍视频后的视频Uri
     */
    fun getTakeVideoUri(context: Context): Uri {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val contentValue = contentValuesOf(
                Pair(
                    MediaStore.MediaColumns.DISPLAY_NAME,
                    "VID_${TimeUtil.getCurrentTime_yyyyMMdd_HHmmss()}.mp4"
                ),
                Pair(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_MOVIES)
            )
            context.contentResolver.insert(
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValue
            )!!
        } else {
            val file = File(
                Environment.getExternalStorageState(),
                "/Movies/VID_${TimeUtil.getCurrentTime_yyyyMMdd_HHmmss()}.mp4"
            )
            context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)?.let {
                val f = File(it, "/VID_${TimeUtil.getCurrentTime_yyyyMMdd_HHmmss()}.mp4")
                FileProvider.getUriForFile(context, authorities, f)
            } ?: FileProvider.getUriForFile(context, authorities, file)
        }
    }

下一步则需要先注册回调,在OnCreate中写就行。

val getVideoResultBack = registerForActivityResult(ActivityResultContractsForCustom.TakeVideo()){
            if (it == true) {
                mVidUri?.let { uri ->
                // 使用Dialog来播放拍完的视频
                val dialog = VideoDialog()
                dialog.setVideoPath(FileUtil.getRealFilePathByUri(this, uri))
                dialog.show(supportFragmentManager, "video")
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
                        val absolutePath = FileUtil.getRealFilePathByUri(this, uri)
                        MediaUtil.mediaInsertVideo(this@MainActivity, absolutePath)
                    }
                }
            }
        }
// 调用相机    mVidUri最好在每次拍照前都把其值重新更新,以免发生新拍的照片将旧照片覆盖的情况   下面方法在按钮点击后调用
getVideoResultBack?.launch(mVidUri)

这里并没有使用系统的ActivityResultContracts.TakeVideo(),主要考虑系统提供的返回bitmap,根据判断是否拍摄完成不太方便,所以采用自定义回调方式,自定义类需要继承:ActivityResultContract<Uri, Boolean?>,返回值类型选择Boolean。

ActivityResultContractsForCustom相关实现

object ActivityResultContractsForCustom {
    class TakeVideo : ActivityResultContract<Uri, Boolean?>() {
        @CallSuper
        override fun createIntent(context: Context, input: Uri): Intent {
            return Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                .putExtra(MediaStore.EXTRA_OUTPUT, input)
        }

        override fun getSynchronousResult(
            context: Context,
            input: Uri
        ): SynchronousResult<Boolean?>? {
            return null
        }

        override fun parseResult(resultCode: Int, intent: Intent?): Boolean? {
            // 根据返回是否成功来判断是否拍完视频后点击完成返回首页
            return resultCode == Activity.RESULT_OK
        }
    }
}

另一种官方文档上提供的Intent方法:

下面都是官方提供的方式

Android 向其他应用委托操作的方法是调用一个 Intent 以描述您要执行的操作。此过程涉及三个部分:Intent 本身,用于启动外部 Activity 的调用,以及用于在焦点返回到 Activity 时处理视频的一些代码。

下面是一个调用 Intent 以拍摄视频的函数。

const val REQUEST_VIDEO_CAPTURE = 1

    private fun dispatchTakeVideoIntent() {
        Intent(MediaStore.ACTION_VIDEO_CAPTURE).also { takeVideoIntent ->
            takeVideoIntent.resolveActivity(packageManager)?.also {
                startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE)
            }
        }
    }

请注意,startActivityForResult() 方法受调用 resolveActivity()(返回可处理 Intent 的第一个 Activity 组件)的条件保护。执行此检查非常重要,因为如果您使用任何应用都无法处理的 Intent 调用 startActivityForResult(),您的应用就会崩溃。所以只要结果不是 Null,就可以放心使用 Intent。

观看视频

Android 相机应用会返回 Intent(作为 Uri 传递给 onActivityResult(),指向视频在存储设备中所处的位置)中的视频。下面的代码会检索此视频并将其显示在一个 VideoView 中。

 override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent) {
        if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {
            val videoUri: Uri = intent.data
            videoView.setVideoURI(videoUri)
        }
    }

项目CameraDemo

相关文章

  • 调用系统相机拍视频并将视频插入相册

    请求相机功能 如果您应用的基本功能是拍照,请将其在 Google Play 上的显示范围限制在装有相机的设备上。如...

  • 3.4 音频播放.视频播放.相册调用.相机调用

    音频播放.视频播放.相册调用.相机调用 音频播放 视频播放 相册调用 视频音频资源 视频音频资源.png

  • 系统相册,相机,拍视频

    #import //资产库框架 #import //移动核心服务框架 @property(nonatomic,st...

  • 调用系统相机拍照并将照片插入相册

    请求相机功能 如果您应用的基本功能是拍照,请将其在 Google Play 上的显示范围限制在装有相机的设备上。如...

  • 系统SDK介绍-02

    系统SDK介绍 打开相册选择图片 打开相册选择视频 打开相机拍摄图片 打开相机拍摄视频 配置权限: 在info.p...

  • 2019-03-22

    GPUImage 之 GPUImageVideoCamera 实现美颜相机功能,并将美颜后的视频保存到手机相册

  • iOS 使用系统相机、相册显示中文

    在调用系统相机时,"cancel" 改为"取消",调用系统相册时,"photos"改为 "相机",方法如下: 1....

  • 工作小结

    在调用系统相机时,"cancel" 改为"取消",调用系统相册时,"photos" 改为 "相机",方法如下: 1...

  • Android录制视频

    1、系统相机 录制视频,最简单的当然是调用系统的相机,可以使用如下参数,配置系统相机: MediaStore.EX...

  • 13.4 camera

    简介 android中相机使用有两种方式,一是调用系统相机(Intent),二是自定义相机 调用系统相机相册 自定...

网友评论

      本文标题:调用系统相机拍视频并将视频插入相册

      本文链接:https://www.haomeiwen.com/subject/uohhtrtx.html