Skip to content

Instantly share code, notes, and snippets.

@uziassantosferreira
Created December 12, 2016 12:36
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save uziassantosferreira/af2eb26d57f40413e11871c741abb4d3 to your computer and use it in GitHub Desktop.
Save uziassantosferreira/af2eb26d57f40413e11871c741abb4d3 to your computer and use it in GitHub Desktop.
Screen Recording in service android
public class MediaRecorderHelper {
private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90;
private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270;
private static final SparseIntArray DEFAULT_ORIENTATIONS = new SparseIntArray();
private static final SparseIntArray INVERSE_ORIENTATIONS = new SparseIntArray();
static {
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_0, 90);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_90, 0);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_180, 270);
DEFAULT_ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
static {
INVERSE_ORIENTATIONS.append(Surface.ROTATION_0, 270);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_90, 180);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_180, 90);
INVERSE_ORIENTATIONS.append(Surface.ROTATION_270, 0);
}
public static MediaRecorder configureRecorder(MediaRecorder mediaRecorder, WindowManager windowManager, int displayWidth, int displayHeight, boolean enableAudio, Integer sensorOrientation){
if (enableAudio){
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
}
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(FileUtils.createTempVideoFile());
mediaRecorder.setVideoSize(displayWidth, displayHeight);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
if (enableAudio){
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
}
mediaRecorder.setVideoEncodingBitRate(10000000);
mediaRecorder.setVideoFrameRate(30);
int rotation = windowManager.getDefaultDisplay().getRotation();
if (sensorOrientation != null){
switch (sensorOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
}else{
int orientation = DEFAULT_ORIENTATIONS.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
}
return mediaRecorder;
}
public static VirtualDisplay createVirtualDisplay(MediaProjection mediaProjection, MediaRecorder mediaRecorder, Context context, int displayWidth, int displayHeight, int density) {
return mediaProjection.createVirtualDisplay(context.getString(R.string.app_name), displayWidth, displayHeight, density,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
}
}
package br.com.testr.services;
import android.app.Service;
import android.content.Intent;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import java.io.IOException;
import br.com.testr.AppApplication;
import br.com.testr.helper.CameraHelper;
import br.com.testr.helper.MediaRecorderHelper;
import br.com.testr.helper.DraggableViewRecordingHelper;
/**
* Created by uzias on 10/3/16.
*/
public class ScreenRecorderService extends Service {
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay;
private MediaProjectionCallback mediaProjectionCallback;
private MediaRecorder mediaRecorder;
private int displayWidth;
private int mDisplayHeight;
private int mDensityDpi;
private WindowManager windowManager;
private DraggableViewRecordingHelper draggableViewRecordingHelper;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mediaRecorder = new MediaRecorder();
DisplayMetrics metrics = getResources().getDisplayMetrics();
mDensityDpi = metrics.densityDpi;
displayWidth = metrics.widthPixels;
mDisplayHeight = metrics.heightPixels;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
draggableViewRecordingHelper = new DraggableViewRecordingHelper(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
initRecorder();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
stopRecorderAndScreen();
}
private void initRecorder() {
try {
if (mediaProjectionCallback == null){
mediaProjectionCallback = new MediaProjectionCallback();
}
mediaProjection = AppApplication.mediaProjection;
if (mediaProjection == null){
hideRecordingViewStopServicesShowError();
return;
}
mediaProjection.registerCallback(mediaProjectionCallback, null);
mediaRecorder = MediaRecorderHelper.configureRecorder(mediaRecorder, windowManager, displayWidth, mDisplayHeight, false, null);
mediaRecorder.prepare();
virtualDisplay = MediaRecorderHelper.createVirtualDisplay(mediaProjection, mediaRecorder, this, displayWidth, mDisplayHeight, mDensityDpi);
mediaRecorder.start();
draggableViewRecordingHelper.showView();
} catch (IOException e) {
e.printStackTrace();
hideRecordingViewStopServicesShowError();
}
}
private void destroyMediaProjection() {
if (mediaProjection != null) {
mediaProjection.unregisterCallback(mediaProjectionCallback);
mediaProjection.stop();
mediaProjection = null;
}
}
private void stopRecorderAndScreen() {
try {
mediaRecorder.stop();
}catch (Exception e){
e.printStackTrace();
hideRecordingViewStopServicesShowError();
}
draggableViewRecordingHelper.hideView();
mediaRecorder.reset();
destroyMediaProjection();
if (virtualDisplay != null) {
virtualDisplay.release();
}
}
private void hideRecordingViewStopServicesShowError(){
CameraHelper.hideRecordingViewStopServicesShowError(this);
}
private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
stopRecorderAndScreen();
}
}
}
@iamjonny
Copy link

Hi @uziassantosferreira !
I just found this whilst looking for one of the many useful things I hoped would be available with a rooted smartphone (android 13 s20)
is this a service that can be loaded early in the "bootup process", to record the screen(s) on the phone, either on device direct (if possible), and/or via windows machine (if required)?

Guessing from filename it does something similar, perhaps not at boot-time, not sure on intended or possible usage, eg if you need to write an app, or can "adb it", or other clever voodoo

Gist wondering 🙂

@uziassantosferreira
Copy link
Author

@iamjonny you can use when start the application but the user need to accept the permission

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment