Android 实现屏幕录制

avatar
作者
猴君
阅读量:0
  1. 添加权限和服务声明

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <service             android:name=".ScreenService"             android:enabled="true"             android:exported="true"             android:foregroundServiceType="mediaProjection"></service> 
  2. 创建屏幕录制的 Service

    import android.app.* import android.content.Context import android.content.Intent import android.graphics.BitmapFactory import android.hardware.display.DisplayManager import android.hardware.display.VirtualDisplay import android.media.CamcorderProfile import android.media.MediaRecorder import android.media.projection.MediaProjection import android.media.projection.MediaProjectionManager import android.os.Build import android.os.IBinder import android.util.DisplayMetrics import android.util.Log import android.view.WindowManager import androidx.core.app.NotificationCompat import java.io.IOException  class ScreenService : Service() {      private var mContext:Context?=null     private var projectionManager:MediaProjectionManager?=null     private var mMediaProjection:MediaProjection?=null     override fun onBind(intent: Intent): IBinder {         TODO("Return the communication channel to the service.")     }      override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {         mContext = this         var resultCode = intent?.getIntExtra("resultCode", -1)         var path = intent?.getStringExtra("path")         var resultData: Intent? = intent?.getParcelableExtra("data")         startNotification();         projectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager         mMediaProjection = resultCode?.let { resultData?.let { it1 -> projectionManager?.getMediaProjection(it, it1) } }         path?.let { startRecording(it) }         return super.onStartCommand(intent, flags, startId)     }      private var NOTIFICATION_CHANNEL_ID="id";     private var NOTIFICATION_CHANNEL_NAME="channel";     private var NOTIFICATION_CHANNEL_DESC="desc";     private fun startNotification() {         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {             var notificationIntent = Intent(mContext, ScreenService::class.java)             var pendingIntent: PendingIntent?=null             pendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {                 PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);             } else {                 PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);             }             var  notificationBuilder = mContext?.let {                 NotificationCompat.Builder(it, NOTIFICATION_CHANNEL_ID)                     .setLargeIcon(BitmapFactory.decodeResource(mContext!!.resources, R.drawable.ic_launcher_foreground))                     .setSmallIcon(R.drawable.ic_launcher_foreground)                     .setContentTitle("start record")                     .setContentText("=== start record ===")                     .setContentIntent(pendingIntent)             };             var  notification = notificationBuilder?.build();             var  channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);             channel.description = NOTIFICATION_CHANNEL_DESC;             var  notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager             notificationManager.createNotificationChannel(channel)             startForeground(1, notification);         }     }       private var isScreenRecoding = false     private var  mMediaRecorder: MediaRecorder?=null     private var mVirtualDisplay: VirtualDisplay? = null     private fun startRecording(filePath:String) {         if (!isScreenRecoding){             try {                 // 创建 MediaRecorder 并设置参数                 val metrics = DisplayMetrics()                 val windowManager: WindowManager = mContext?.getSystemService(WINDOW_SERVICE) as WindowManager                 windowManager.defaultDisplay.getMetrics(metrics)                 mMediaRecorder = MediaRecorder()                 mMediaRecorder?.setVideoSource(MediaRecorder.VideoSource.SURFACE)                 mMediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)                 mMediaRecorder?.setOutputFile(filePath)                 mMediaRecorder?.setVideoSize(metrics.widthPixels, metrics.heightPixels)                 mMediaRecorder?.setVideoEncoder(MediaRecorder.VideoEncoder.H264)                 mMediaRecorder?.setVideoEncodingBitRate(1920*1080 * 3)                 mMediaRecorder?.setVideoFrameRate(30)                  // 准备 MediaRecorder                 mMediaRecorder?.prepare()                  // 创建 VirtualDisplay 以获取屏幕内容                 mVirtualDisplay = mMediaProjection?.createVirtualDisplay(                     "ScreenRecord",                     metrics.widthPixels, metrics.heightPixels, metrics.densityDpi,                     DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,                     mMediaRecorder?.surface, null, null                 )                  // 开始录制                 mMediaRecorder?.start()                 isScreenRecoding = true                 Log.i(ScreenUtil.TAG,"开始录屏 $filePath")             } catch (e: IOException) {                 Log.e(ScreenUtil.TAG, "录屏失败: " + e.message)                 e.printStackTrace()             }         }     }     public fun stopRecording() {         if (isScreenRecoding) {             try {                 // 停止录制                 mMediaRecorder?.stop()                 mMediaRecorder?.reset()                 mMediaRecorder?.release()                 mMediaRecorder = null                  // 停止 VirtualDisplay                 mVirtualDisplay?.release()                  // 停止 MediaProjection                 mMediaProjection?.stop()                 Log.i(ScreenUtil.TAG,"结束录屏")             } catch (e: Exception) {                 Log.e(ScreenUtil.TAG, "停止录屏失败: " + e.message)                 e.printStackTrace()             }             isScreenRecoding = false         }     }      override fun onDestroy() {         stopRecording()         super.onDestroy()     } } 
  3. 启动和停止录制

    private var mProjectionManager: MediaProjectionManager? = null var screenService:Intent?=null fun start(){ 	mProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager 	// 请求录屏权限 	startActivityForResult(mProjectionManager?.createScreenCaptureIntent(), 500); } fun stop(){ 	stopService(screenService) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {     super.onActivityResult(requestCode, resultCode, data)     if (requestCode == 500){         screenService = Intent(mConext, ScreenService::class.java)         screenService?.let {             it.putExtra("resultCode", resultCode);             it.putExtra("data", data);             it.putExtra("path", "screen.mp4");             startForegroundService(it)         }     } } 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!