mediarecorder 录制的文件无法拖动进度条_百万级日活 App 的屏幕录制功能是如何实现的...

推荐阅读:

一年Android开发经验,知乎网易蘑菇街阿里面经,已拿网易offer

Android开发该何去何从——来自安卓程序员的焦虑

2019年字节跳动腾讯Android面试必问:性能优化+JNI+布局+WebView

095b961f8d54c408a485398fdf09b44d.png

Android 从 4.0 开始就提供了手机录屏方法,但是需要 root 权限,比较麻烦不容易实现。但是从 5.0 开始,系统提供给了 App 录制屏幕的一系列方法,不需要 root 权限,只需要用户授权即可录屏,相对来说较为简单。

基本上根据 官方文档 便可以写出录屏的相关代码。

屏幕录制的基本实现步骤

在 Manifest 中申明权限

获取 MediaProjectionManager 并申请权限

private val mediaProjectionManager by lazy { activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as? MediaProjectionManager }private var mediaProjection: MediaProjection? = nullif (mediaProjectionManager == null) { Log.d(TAG, "mediaProjectionManager == null,当前手机暂不支持录屏") showToast(R.string.phone_not_support_screen_record) return}// 申请相关权限PermissionUtils.permission(PermissionConstants.STORAGE, PermissionConstants.MICROPHONE) .callback(object : PermissionUtils.SimpleCallback { override fun onGranted() { Log.d(TAG, "start record") mediaProjectionManager?.apply { // 申请相关权限成功后,要向用户申请录屏对话框 val intent = this.createScreenCaptureIntent() if (activity.packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { activity.startActivityForResult(intent, REQUEST_CODE) } else { showToast(R.string.phone_not_support_screen_record) } } } override fun onDenied() { showToast(R.string.permission_denied) } }) .request()

重写 onActivityResult() 对用户授权进行处理

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { if (requestCode == REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { mediaProjection = mediaProjectionManager!!.getMediaProjection(resultCode, data) // 实测,部分手机上录制视频的时候会有弹窗的出现,所以我们需要做一个 150ms 的延迟 Handler().postDelayed({ if (initRecorder()) { mediaRecorder?.start() } else { showToast(R.string.phone_not_support_screen_record) } }, 150) } else { showToast(R.string.phone_not_support_screen_record) } }}private fun initRecorder(): Boolean { Log.d(TAG, "initRecorder") var result = true // 创建文件夹 val f = File(savePath) if (!f.exists()) { f.mkdirs() } // 录屏保存的文件 saveFile = File(savePath, "$saveName.tmp") saveFile?.apply { if (exists()) { delete() } } mediaRecorder = MediaRecorder() val width = Math.min(displayMetrics.widthPixels, 1080) val height = Math.min(displayMetrics.heightPixels, 1920) mediaRecorder?.apply { // 可以设置是否录制音频 if (recordAudio) { setAudioSource(MediaRecorder.AudioSource.MIC) } setVideoSource(MediaRecorder.VideoSource.SURFACE) setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setVideoEncoder(MediaRecorder.VideoEncoder.H264) if (recordAudio){ setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) } setOutputFile(saveFile!!.absolutePath) setVideoSize(width, height) setVideoEncodingBitRate(8388608) setVideoFrameRate(VIDEO_FRAME_RATE) try { prepare() virtualDisplay = mediaProjection?.createVirtualDisplay("MainScreen
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值