简体   繁体   中英

Android - How to get a screen recording's frames in real time using MediaRecorder

I am trying to create an app that records the device's screen and displays it to an ImageView frame by frame. So far I have only implemented a screen recorder sourced from this link . When the recording is stopped it is saved to a file. Instead of saving the recording to a file, I wish to retrieve each frame and display to an ImageView. Using the MediaRecorder API, is there any way to do this?

RecordingSession.java

class RecordingSession
  implements MediaScannerConnection.OnScanCompletedListener {
  static final int VIRT_DISPLAY_FLAGS=
    DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
      DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
  private RecordingConfig config;
  private final File output;
  private final Context ctxt;
  private final ToneGenerator beeper;
  private MediaRecorder recorder;
  private MediaProjection projection;
  private VirtualDisplay vdisplay;

  RecordingSession(Context ctxt, RecordingConfig config,
                   MediaProjection projection) {
    this.ctxt=ctxt.getApplicationContext();
    this.config=config;
    this.projection=projection;
    this.beeper=new ToneGenerator(
      AudioManager.STREAM_NOTIFICATION, 100);

    output=new File(ctxt.getExternalFilesDir(null), "andcorder.mp4");
    output.getParentFile().mkdirs();
  }

  void start() {
    recorder=new MediaRecorder();
    recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setVideoFrameRate(config.frameRate);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoSize(config.width, config.height);
    recorder.setVideoEncodingBitRate(config.bitRate);
    recorder.setOutputFile(output.getAbsolutePath());

    try {
      recorder.prepare();
      vdisplay=projection.createVirtualDisplay("andcorder",
        config.width, config.height, config.density,
        VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
      beeper.startTone(ToneGenerator.TONE_PROP_ACK);
      recorder.start();
    }
    catch (IOException e) {
      throw new RuntimeException("Exception preparing recorder", e);
    }
  }

  void stop() {
    projection.stop();
    recorder.stop();
    recorder.release();
    vdisplay.release();

    MediaScannerConnection.scanFile(ctxt,
      new String[]{output.getAbsolutePath()}, null, this);
  }

  @Override
  public void onScanCompleted(String path, Uri uri) {
    beeper.startTone(ToneGenerator.TONE_PROP_NACK);
  }
}

You wouldn't do an ImageView for this. You'd use a SurfaceView. It's meant to be used for things like media playback. https://developer.android.com/reference/android/view/SurfaceView?hl=en

You can find a bunch of examples on how to use it on Google, such as https://gist.github.com/scottgwald/7743453

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM