如何使用Android API记录屏幕并截取屏幕截图?

时间:2015-09-10 23:55:38

标签: android screenshot android-5.0-lollipop android-4.4-kitkat screen-recording

背景

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

自新API发布以来,许多应用程序都使用此功能,允许录制屏幕,微软甚至制作了自己的Google-Now-On-tap竞争对手应用程序。

使用ADB,您可以使用:

adb shell screenrecord /sdcard/video.mp4 

您甚至可以在Android Studio内部进行此操作。

问题

我无法使用API​​找到有关如何使用API​​的任何教程或说明,这意味着在代码中。

我发现了什么

我找到的唯一地方是文档(here,屏幕截图和分享#34;),告诉我:

  

Android 5.0允许您添加屏幕捕获和屏幕共享   使用新的android.media.projection API为您的应用程序提供的功能。   例如,如果要启用此功能,则此功能非常有用   视频会议应用中的屏幕共享。

     

新的createVirtualDisplay()方法允许您的应用捕获   主屏幕的内容(默认显示)进入Surface   对象,然后您的应用可以通过网络发送。仅限API   允许捕获非安全屏幕内容,而不是系统音频。至   开始屏幕捕获,您的应用必须首先请求用户   通过使用Intent启动屏幕捕获对话框来获得权限   通过createScreenCaptureIntent()方法获得。

     

有关如何使用新API的示例,请参阅MediaProjectionDemo   示例项目中的类。

事情是,我无法找到任何" MediaProjectionDemo"样品。相反,我发现了" Screen Capture"示例,但我不明白它是如何工作的,因为当我运行它时,我所看到的只是一个闪烁的屏幕,我不认为它将视频保存到文件中。样本似乎非常错误。

问题

如何使用新API执行这些操作:

  1. 开始录制,可选择包括音频(麦克风/扬声器/两者)。
  2. 停止录制
  3. 截取屏幕截图而不是视频。
  4. 另外,我如何自定义它(分辨率,请求的fps,颜色,时间......)?

1 个答案:

答案 0 :(得分:60)

第一步和Ken White正确建议的那一步&您可能已经涵盖的是正式提供的Example Code

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

我将在3个部分回答您的问题,并将链接包起来。 :)

<强> 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。截取屏幕截图而不是视频

  

我认为默认情况下它很容易以位图格式捕获图像。您仍然可以使用MediaProjectionDemo示例来捕获屏幕截图。

[编辑]:代码加密截图

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

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);

<强>湾然后根据意图或操作启动屏幕捕获 -

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

停止媒体投影 -

sMediaProjection.stop();

<强>℃。然后转换为图片 -

//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();

有多种实施(完整代码)的Media Projection API 可用。 其他一些可以帮助您进行开发的链接 -

  1. Video Recording with MediaProjectionManager - 网站

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

  4. screenrecorder - github

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

  6. 希望它有所帮助:)快乐的编码和屏幕录制!

    PS:你能告诉我你正在谈论的微软应用吗?我没用过它。想尝试一下:)