I am capturing my Android device's screen using the MediaProjection
API by creating a VirtualDisplay
and displaying it on a SurfaceView
that remains always visible. I would like to perform some image processing on the frames grabbed by the VirtualDisplay then draw them back to the SurfaceView, all in real time. Is there any way to do this with the VirtualDisplay and MediaProjection APIs?
RecordingSession.java
class RecordingSession implements SurfaceHolder.Callback {
static final int VIRT_DISPLAY_FLAGS=
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private RecordingConfig config;
private final Context ctxt;
private final ToneGenerator beeper;
private MediaRecorder recorder;
private MediaProjection projection;
private VirtualDisplay vdisplay;
private Window window;
private Bitmap latestBitmap=null;
RecordingSession(Context ctxt, RecordingConfig config,
MediaProjection projection, Window window) {
this.ctxt=ctxt.getApplicationContext();
this.window = window;
this.config=config;
this.projection=projection;
this.beeper=new ToneGenerator(
AudioManager.STREAM_NOTIFICATION, 100);
}
void start() {
this.window = new Window(this.ctxt);
this.window.open();
this.window.getScreenShot().getHolder().addCallback(this);
vdisplay=projection.createVirtualDisplay("andcorder",
config.width*4, config.height*4, config.density,
VIRT_DISPLAY_FLAGS, null, null, null);
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
}
void stop() {
projection.stop();
vdisplay.release();
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
vdisplay.setSurface(surfaceHolder.getSurface());
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
}
public void end() {
this.window.close();
}
}