Screen recorder - Android
Basic code to record screen on Android.
Record your app and other apps
override fun onStartCommand (intent : Intent ? , flags : Int , startId : Int ): Int {
intent ? : return super .onStartCommand(intent, flags, startId)
val extras = intent.extras
? : return super .onStartCommand(intent, flags, startId)
val action = extras.getString(" action" )
? : return super .onStartCommand(intent, flags, startId)
when (action) {
" start" -> {
val resultCode = extras.getInt(" result_code" )
fileOutputPath = extras.getString(" file_output_path" )!!
val data = extras.getParcelable<Intent >(" data" )!!
getAudioPcmFile().delete()
getVideoNoSoundMp4File().delete()
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data)
mediaProjection!! .registerCallback(mediaProjectionCallback, null )
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
val config =
AudioPlaybackCaptureConfiguration .Builder (mediaProjection!! )
.addMatchingUsage(AudioAttributes .USAGE_MEDIA )
.build()
val audioFormat: AudioFormat = AudioFormat .Builder ()
.setEncoding(audioFormat)
.setSampleRate(sampleRateInHz)
.setChannelMask(audioChannelConfig)
.build()
audioRecord = AudioRecord .Builder ()
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(bufferSizeInBytes * audioNbChannels)
.setAudioPlaybackCaptureConfig(config)
.build()
audioRecord!! .startRecording()
audioRecordingThread = createAudioRecordingThread()
audioRecordingThread!! .start()
}
mediaRecorder = createMediaRecorder(getVideoNoSoundMp4File())
virtualDisplay = createVirtualDisplay(mediaRecorder!! )
mediaRecorder!! .start()
}
" stop" -> {
val wasRecording = isAudioRecording()
virtualDisplay?.release()
mediaProjection?.unregisterCallback(mediaProjectionCallback)
mediaProjection?.stop()
audioRecord?.stop()
mediaRecorder?.stop()
mediaRecorder?.reset()
mediaRecorder = null
virtualDisplay = null
if (! wasRecording) {
stopForeground(true )
stopSelf()
}
}
}
return super .onStartCommand(intent, flags, startId)
}
private fun createVirtualDisplay (mediaRecorder : MediaRecorder ): VirtualDisplay {
val metrics = DisplayMetrics ()
ScreenRecordGraph .getWindowManager().defaultDisplay.getMetrics(metrics)
return mediaProjection!! .createVirtualDisplay(
" MainActivity" ,
ScreenRecordGraph .DISPLAY_WIDTH ,
ScreenRecordGraph .DISPLAY_HEIGHT ,
metrics.densityDpi,
DisplayManager .VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR ,
mediaRecorder.surface,
null ,
null
)
}
private fun createMediaRecorder (outputFile : File ): MediaRecorder {
val mediaRecorder = MediaRecorder ()
mediaRecorder.setAudioSource(MediaRecorder .AudioSource .DEFAULT )
mediaRecorder.setVideoSource(MediaRecorder .VideoSource .SURFACE )
mediaRecorder.setOutputFormat(MediaRecorder .OutputFormat .MPEG_4 )
mediaRecorder.setOutputFile(outputFile.absolutePath)
mediaRecorder.setVideoSize(
ScreenRecordGraph .DISPLAY_WIDTH ,
ScreenRecordGraph .DISPLAY_HEIGHT
)
mediaRecorder.setVideoEncoder(MediaRecorder .VideoEncoder .H264 )
mediaRecorder.setAudioEncoder(MediaRecorder .AudioEncoder .AMR_NB )
mediaRecorder.setVideoEncodingBitRate(512 * 1_000 )
mediaRecorder.setVideoFrameRate(16 ) // 30
mediaRecorder.setVideoEncodingBitRate(3_000_000 )
val rotation = windowManager.defaultDisplay.rotation
val orientation = ORIENTATIONS .get(rotation + 90 )
mediaRecorder.setOrientationHint(orientation)
mediaRecorder.prepare()
return mediaRecorder
}
companion object {
private val ORIENTATIONS = SparseIntArray ()
init {
ORIENTATIONS .append(Surface .ROTATION_0 , 90 )
ORIENTATIONS .append(Surface .ROTATION_90 , 0 )
ORIENTATIONS .append(Surface .ROTATION_180 , 270 )
ORIENTATIONS .append(Surface .ROTATION_270 , 180 )
}
}