如何使用AndroidAPI录屏截屏?

How to record screen and take screenshots, using Android API?

背景

Android 在 Kitkat 和 Lollipop 上获得了一个新的 API,用于视频捕获屏幕。您可以通过 ADB 工具或通过代码(从 Lollipop 开始)来完成。

自从新的 API 出来后,许多应用程序开始使用此功能,允许录制屏幕,微软甚至推出了自己的 Google-Now-On-tap 竞争对手应用

使用ADB,您可以使用:

adb shell screenrecord /sdcard/video.mp4 

您甚至可以在 Android Studio 中完成。

问题

我找不到任何关于如何使用 API 进行操作的教程或解释,意思是代码。

我发现了什么

我找到的唯一地方是文档(here,在 "Screen capturing and sharing" 下),告诉我:

Android 5.0 lets you add screen capturing and screen sharing capabilities to your app with the new android.media.projection APIs. This functionality is useful, for example, if you want to enable screen sharing in a video conferencing app.

The new createVirtualDisplay() method allows your app to capture the contents of the main screen (the default display) into a Surface object, which your app can then send across the network. The API only allows capturing non-secure screen content, and not system audio. To begin screen capturing, your app must first request the user’s permission by launching a screen capture dialog using an Intent obtained through the createScreenCaptureIntent() method.

For an example of how to use the new APIs, see the MediaProjectionDemo class in the sample project.

问题是,我找不到任何 "MediaProjectionDemo" 样本。相反,我找到了 "Screen Capture" 样本,但我不明白它是如何工作的,因为当我 运行 它时,我所看到的只是一个闪烁的屏幕,我不认为它将视频保存到文件中。该示例似乎有很多问题。

问题

如何使用新的 API:

执行这些操作
  1. 开始录制,可选择包括音频 (mic/speaker/both)。
  2. 停止录制
  3. 截屏而不是视频。

此外,我如何自定义它(分辨率、要求的 fps、颜色、时间...)?

Ken White 正确建议的第一步,您可能已经介绍过的是官方提供的Example Code

我之前用过他们的API。我同意屏幕截图非常简单。但是,屏幕录制也有类似的行。

我将分 3 个部分回答您的问题,并以 link 结尾。 :)


1.开始录像

private void startScreenRecord(final Intent intent) {
 if (DEBUG) Log.v(TAG, "startScreenRecord:sMuxer=" + sMuxer);
 synchronized(sSync) {
  if (sMuxer == null) {
   final int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0);
   // get MediaProjection 
   final MediaProjection projection = mMediaProjectionManager.getMediaProjection(resultCode, intent);
   if (projection != null) {
    final DisplayMetrics metrics = getResources().getDisplayMetrics();
    final int density = metrics.densityDpi;

    if (DEBUG) Log.v(TAG, "startRecording:");
    try {
     sMuxer = new MediaMuxerWrapper(".mp4"); // if you record audio only, ".m4a" is also OK. 
     if (true) {
      // for screen capturing 
      new MediaScreenEncoder(sMuxer, mMediaEncoderListener,
       projection, metrics.widthPixels, metrics.heightPixels, density);
     }
     if (true) {
      // for audio capturing 
      new MediaAudioEncoder(sMuxer, mMediaEncoderListener);
     }
     sMuxer.prepare();
     sMuxer.startRecording();
    } catch (final IOException e) {
     Log.e(TAG, "startScreenRecord:", e);
    }
   }
  }
 }
}

2。停止录像

 private void stopScreenRecord() {
  if (DEBUG) Log.v(TAG, "stopScreenRecord:sMuxer=" + sMuxer);
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.stopRecording();
    sMuxer = null;
    // you should not wait here 
   }
  }
 }

2.5。暂停和恢复视频录制

 private void pauseScreenRecord() {
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.pauseRecording();
   }
  }
 }

 private void resumeScreenRecord() {
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.resumeRecording();
   }
  }
 }

希望代码对您有所帮助。这是我引用的代码的 original link,此实现(视频录制)也源自该代码。


3。截图而不是视频

I think by default its easy to capture the image in bitmap format. You can still go ahead with MediaProjectionDemo example to capture screenshot.

[编辑]:截图加密代码

一个。根据设备宽度/高度创建虚拟显示

mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);

b.然后根据意图或动作开始屏幕捕获-

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

停止媒体投影-

sMediaProjection.stop();

c.然后转换为图像-

//Process the media capture
image = mImageReader.acquireLatestImage();
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mWidth;
//Create bitmap
bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
//Write Bitmap to file in some path on the phone
fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
bitmap.compress(CompressFormat.PNG, 100, fos);
fos.close();

媒体投影 API 有多种实现方式 (完整代码)可用。 其他一些可以帮助您发展的link-

  1. Video Recording with MediaProjectionManager - 网站

  2. android-ScreenCapture - github 根据 android 开发者的观察:)

  3. screenrecorder - github

  4. Capture and Record Android Screen using MediaProjection APIs - 网站


希望对您有所帮助:)祝您编码和屏幕录制愉快!

PS:你能告诉我你说的微软应用吗?我没用过。想试试:)