Android在5.0系统之前,是没有开放视频录制的接口的,如果要录制视频,必须要先root,这部分我会在随后的博客中细讲。
在5.0,Google终于开放了视频录制的接口(其实严格来说,是屏幕采集的接口),也就是MediaProjection和MediaProjectionManager。
首先来说MediaProjectionManager,它是一个系统级的服务,类似WindowManager,AlarmManager等,你可以通过getSystemService方法来获取它的实例:
- 1
- 1
获取到实例后,录像的过程如下(有点像拍照的流程):
首先:
- 1
- 2
- 1
- 2
createScreenCaptureIntent方法的注释如下:
/** * Returns an Intent that <b>must</b> passed to startActivityForResult() * in order to start screen capture. The activity will prompt * the user whether to allow screen capture. The result of this * activity should be passed to getMediaProjection. */
大致意思是,这个方法会返回一个intent,你可以通过startActivityForResult方法来传递这个intent,为了能开始屏幕捕捉,activity会提示用户是否允许屏幕捕捉(为了防止开发者做一个木马,来捕获用户私人信息),你可以通过getMediaProjection来获取屏幕捕捉的结果。
createScreenCaptureIntent的代码我们可以看一下:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
看着很眼熟是吧,拍照的是这样:
- 1
- 2
- 1
- 2
所以这里是创建了一个隐式的intent,用来调用系统的录屏程序。
然后正如上面的注释所说,我们通过startActivityForResult来传递这个intent,所以我们可以通过onActivityResult来获取结果,通过getMediaProjection来取出intent中的数据:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
我们通过getMediaProjection获取到mediaProjection,并注册了一个callback回调。
看看createVirtualDisplay做了什么:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
可以看到,我们调用了MediaProjection的createVirtualDisplay方法,来创建了一个VirtualDisplay的实例,说几个createVirtualDisplay的参数含义:
name 是生成的VirtualDisplay实例的名称;
width和height分别是生成实例的宽高,必须大于0;
dpi,生成实例的像素密度,必须大于0,一般都取1;
surface,这个比较重要,是你生成的VirtualDisplay的载体,我的理解是,VirtualDisplay的内容是一帧帧的屏幕截图(所以你看到是有宽高,像素密度等设置),所以MediaProjection获取到的其实是一帧帧的图,然后通过surface(surface你可以理解成是android的一个画布,默认它会以每秒60帧来刷新,这里我们不再展开细说),来顺序播放这些图片,形成视频。
surface我们可以这样获取到:
- 1
- 2
- 1
- 2
对应的我们要在XML里面写一个SurfaceView的控件:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
这样,屏幕所捕获的内容,就显示在这个SurfaceView上面了