Android 拍照/录像/文件选取/获取视频第一帧(含完整 Demo)

745 阅读3分钟

废话不多说,直接看效果:

录像拍照文件选取(获取第一帧图片)
32484AF56C712B5B20588E8B5854A852.gifD0C226DE9F4BCCFC1E9BCEB925F0C901.gifF3057F2717794986D8F4B286317D1A4A.gif

注:

  • 录像/拍照是使用的一个开源框架,里面的东西稍作了调整.原地址我找不到了(如有雷同,请私信联系我,本篇只当做笔记来记录!)

工作前的准备

本篇涉及到了使用相机,保存文件等操作,所以需要先申请权限

权限申请是采用郭霖大佬的开源库 permissionX

直接贴上完整代码:

//申请权限
    private fun initPermission() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.CAMERA
            )
            //onExplainRequestReason当用户拒绝权限的时候执行
            .onExplainRequestReason { deniedList ->
                showRequestReasonDialog(deniedList, "即将重新申请的权限是程序必须依赖的权限", "我已明白", "取消")
            }
            //onForwardToSettings 监听用户永久拒绝的权限
            .onForwardToSettings {
                showForwardToSettingsDialog(it, "您需要去应用程序设置当中手动开启权限", "我已明白", "取消")
            }
            /**
             * 参数一: 所有权限是否通过
             * 参数二: 用于记录所有已被授权的权限,
             * 参数三: 用于记录所有被拒绝的权限。
             */
            .request { allGranted, _, _ ->
                run {
                    if (allGranted) {
                        //权限通过了
                    } else {
                        showToast("权限未通过")
                    }
                }
            }
    }

记得在 AndroidManifest.xml 中申请哦

image.png

在 Android10(targetSdkVersion >= 29) 以上存储文件还需要添加一个:

image.png

拍照/视频录像

跳转到CameraActivity页面即可,CameraActivity页面是 library,下载完整 Demo 导入进去即可

  • maxTime 为拍摄时间最大值(单位:s)默认 15s
  • minTime 为拍摄时间最小值(单位:s)默认 1s
        val intent = Intent(this, CameraActivity::class.java)

        //设置拍摄最大值 单位:秒
        intent.putExtra("maxTime", 20)
        //设置拍摄最小值 单位:秒
        intent.putExtra("minTime", 1)
        startActivityForResult(intent, 100)

接收CameraActivity页面的回调

  • 101 为成功 回调图片路径
  • 103 为没有没有权限
  • 104 为视频文件回调(下面会用)
 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.i("szjCode", "$resultCode\t$requestCode")

        if (resultCode == 101) {
            val path = data?.getStringExtra("path")
            //设置回调第一帧照片
            photo.setImageBitmap(BitmapFactory.decodeFile(path))
        }

        if (resultCode == 103) {
            Toast.makeText(this, "请检查相机权限~", Toast.LENGTH_SHORT).show()
        }

        //文件上传回调
        if (requestCode == 104) {
            //获取图片完整路径
            val path = ContentUriUtil.getPath(this, data?.data)
            Log.i("filepath", " = $path")

            showToast("您选择的视频完整路径为:$path")
            //获取图片第一帧 并且赋值
            getVideoThumbnail(path)
        }
    }

在来回顾一下效果图:

录屏拍照
32484AF56C712B5B20588E8B5854A852.gifD0C226DE9F4BCCFC1E9BCEB925F0C901.gif

获取视频文件第一帧

获取视频文件第一帧首先需要获取完整的视频路径

进入视频文件选取页面(只选取视频)

        val intent = Intent()
        /* 开启Pictures画面Type设定为image */
        //intent.setType("image/*");
        // intent.setType("audio/*"); //选择音频
        intent.type = "video/*" //选择视频 (mp4 3gp 是android支持的视频格式)

        // intent.setType("video/*;image/*");//同时选择视频和图片

        /* 使用Intent.ACTION_GET_CONTENT这个Action */
        intent.action = Intent.ACTION_GET_CONTENT
        /* 取得相片后返回本画面 */
        startActivityForResult(intent, 104)

视频文件回调

  • ContentUriUtil.getPath(this, data?.data)通过 url 获取选取视频路径,这个类是我在网上找的,亲测有用
  • getVideoThumbnail() 获取视频文件第一帧
 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.i("szjCode", "$resultCode\t$requestCode")
           ....
           
        //文件上传回调
        if (requestCode == 104) {
            //获取图片完整路径
            val path = ContentUriUtil.getPath(this, data?.data)
            Log.i("filepath", " = $path")

            showToast("您选择的视频完整路径为:$path")
            //获取图片第一帧 并且赋值
            getVideoThumbnail(path)
        }
    }

获取视频文件第一帧图片:

//获取视频文件第一帧图片
    private fun getVideoThumbnail(url: String?) {
        val bitmap: Bitmap?
        //MediaMetadataRetriever 是android中定义好的一个类,提供了统一
        //的接口,用于从输入的媒体文件中取得帧和元数据;
        val retriever = MediaMetadataRetriever()
        //()根据文件路径获取缩略图
        retriever.setDataSource(url);

        //获得第一帧图片
        bitmap = retriever.frameAtTime

        //设置图片
        photo.setImageBitmap(bitmap)
        //释放
        retriever.release()
    }

最后来回顾一下效果:

F3057F2717794986D8F4B286317D1A4A.gif

课外知识

快速获取控件 Id

 //在plugins中添加 kotlin应用扩展插件
    id 'kotlin-android-extensions'

image.png

使用:

image.png

需要添加一个导包哦: (commond + enter 直接就出来了)

image.png

这个插件出来挺久了,我是 49 年的国军,刚吧 kt 引入项目,所以刚刚知道.挺好用的推荐给和我一样不知道的同学~

完整代码

原创不易,您的点赞就是对我最大的支持!