如何使用 Android API 录制屏幕并截取屏幕截图? [英] How to record screen and take screenshots, using Android API?

查看:103
本文介绍了如何使用 Android API 录制屏幕并截取屏幕截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Android got a new API on Kitkat and Lollipop, to video capture the screen. You can do it either via the ADB tool or via code (starting from Lollipop).

自从新的 API 推出后,很多应用都使用了这个功能,允许记录屏幕,微软甚至制作了自己的 Google-Now-On-tap 竞争对手应用.

Ever since the new API was out, many apps came to that use this feature, allowing to record the screen, and Microsoft even made its own Google-Now-On-tap competitor app.

使用亚行,你可以使用:

Using ADB, you can use:

adb shell screenrecord /sdcard/video.mp4 

您甚至可以在 Android Studio 内部完成.

You can even do it from within Android Studio itself.

我在代码中找不到任何关于如何使用 API 进行操作的教程或解释.

I can't find any tutorial or explanation about how to do it using the API, meaning in code.

我找到的唯一地方是文档(在这里,在屏幕捕获和共享"下),告诉我:

The only place I've found is the documentations (here, under "Screen capturing and sharing"), telling me this:

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

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.

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

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.

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

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

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

Thing is, I can't find any "MediaProjectionDemo" sample. Instead, I've found "Screen Capture" sample, but I don't understand how it works, as when I've run it, all I've seen is a blinking screen and I don't think it saves the video to a file. The sample seems very buggy.

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

How do I perform those actions using the new API:

  1. 开始录音,可以选择包括音频(麦克风/扬声器/两者).
  2. 停止录制
  3. 截取屏幕截图而不是视频.

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

Also, how do I customize it (resolution, requested fps, colors, time...)?

推荐答案

第一步,也是 Ken White 正确建议 &您可能已经涵盖了 示例代码 官方提供.

First step and the one which Ken White rightly suggested & which you may have already covered is the Example Code provided officially.

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

I have used their API earlier. I agree screenshot is pretty straight forward. But, screen recording is also under similar lines.

我将分 3 个部分回答您的问题,并附上一个链接.:)

I will answer your questions in 3 sections and will wrap it up with a 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();
   }
  }
 }

希望代码有帮助.这是 原始链接 指向我引用的代码,该实现(视频录制)也源自该代码.

Hope the code helps. Here is the original link to the code that I referred to and from which this implementation(Video recording) is also derived from.

3.截屏而不是视频

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

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

<小时>

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


There are several implementations (full code) of Media Projection API available. Some other links that can help you in your development-

  1. 使用 MediaProjectionManager 录制视频 - 网站

android-ScreenCapture - github 根据 android开发人员的观察 :)

android-ScreenCapture - github as per android developer's observations :)

screenrecorder - github

捕获和记录 Android使用 MediaProjection API 的屏幕 - 网站

<小时>

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


Hope it helps :) Happy coding and screen recording!

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

这篇关于如何使用 Android API 录制屏幕并截取屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆