加载中 ...
首页 > 常见问题 正文

ShareREC for Android全系统手机录屏软件原理解析

2019-03-24 10:32:20 来源:沈阳软件公司 作者:沈阳软件开发

自安卓4.4最先,系统提供了内置的录屏功效,用户可以在adb下执行screenrecord下令,以指定码率、帧率、分辨率和时长来录制屏幕。但这个方案有弱点,通俗用户无法直接执行adb下令,只能要么求助于adb终端,好比pc端的android-sdk,又或者在安卓装备上获取root权限,再执行录屏下令。幸而从5.1最先,系统又提供了MediaProjection API,通过再组合MediaRecorder或者MediaCodec API,开发者可以十分轻松地实现一个免root的全系统录屏工具,而ShareREC的全系统手机录屏软件原理,正是基于这种组合。

基于MediaProjection来实现录屏有两种方案,若是联合MediaRecorder,则前者为输入,后者为输出,原理清晰,实现简朴,代码也很少。但若是联合的是MediaCodec,则由于后者仅仅只是一个编码器,我们要仔细思量接纳什么样子的数据作为编码输入,编码后要将数据输出到什么工具上压制为视频文件等等,原理庞大,实现难题,代码也许多。但相比力而言,第二个方案自由度很高,站在ShareREC的态度,我们除了全系统录屏,另有此外应用内录屏工具,这些工具已经实现了基于MediaCodec的方案;加之我们还要思量输出的媒体流可能不是存为文件,而是作为流媒体传输,MediaRecorder是很难知足要求的。故而ShareREC使用的是第二套方案。

但本文会将这两套方案都先容一遍,因此让我们由浅及深一步步来吧。

方案一:使用MediaRecorder作为媒体输出

让我们先来看一下MediaProjection API是个什么工具。顾名思义,它是一套“屏幕镜像”工具,焦点类包罗:MediaProjectionManager、MediaProjection和VirtualDisplay。

其中MediaProjectionManager用于向用户显示一个弹窗,请求获取屏幕镜像的权限(如下图)。此弹窗的操作效果会通过Activity的onActivityResult返回,RESULT_OK表现用户已经给了权限。

private MediaProjectionManager mpm;

private void showDialog() {

mpm = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);

Intent captureIntent = mpm.createScreenCaptureIntent();

startActivityForResult(captureIntent, REQUEST_CODE);

}

public void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == REQUEST_CODE) {

// 今后处最先抓屏操作

CreateMediaRecorder();

createVirtualDisplay(data);

}

}

获得权限后,可以挪用MediaProjectionManager的getMediaProjection要领获取MediaProjection实例,并用此实例建立一个VirtualDisplay,这个就是我们的屏幕镜像。

建立VirtualDisplay时需要一个surface做出输出缓存,即存放即将显示在屏幕上的数据。另一方面,自安卓5.1以后,系统为MediaRecorder提供多了一种新的图形输入方式,我们可以通过实在例要领getSurface获得一个surface作为输入缓存。云云联合起来,在录屏的场景中,我们可以先从MediaRecorder中获得一个输入缓存,并将这个缓存当做VirtualDisplay的输出缓存,形成I/O流通、内存共享。

private MediaRecorder mr;

private MediaProjection mp;

private VirtualDisplay vd;

private Callback cb;

private void CreateMediaRecorder() {

try {

mr = new MediaRecorder();

mr.setAudioSource(MediaRecorder.AudioSource.MIC);

mr.setVideoSource(MediaRecorder.VideoSource.SURFACE);

mr.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

mr.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

mr.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

mr.setVideoEncodingBitRate(bitRate);

mr.setVideoFrameRate(30);

mr.setVideoSize(1280, 720);

mr.setOutputFile(“/sdcard/test.mp4”);

mr.prepare();

} catch (Throwable t) {

t.printStackTrace();

}

}

private void createVirtualDisplay(Intent data) {

MediaProjection mp = mpm.getMediaProjection(RESULT_OK, data);

cb = new Callback() {

public void onStop() {

if (mr != null) {

mr.stop();

mr.release();

mr = null;

}

if (vd != null) {

vd.release();

vd = null;

}

}

};

mp.registerCallback(cb, null);

int densityDpi = (int) (getResources().getDisplayMetrics().densityDpi + 0.5f);

vd = mp.createVirtualDisplay("ShareREC",

1280, 720, densityDpi,

DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,

mr.getSurface(), null, null);

mr.start();

}

经由上面的代码,程序已经进入录屏模式。MediaRecorder将以h264/aac为编码花样,将录制的效果以mp4花样存储在sd卡的test.mp4中。

“沈阳软件公司”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与

我们联系删除或处理,客服QQ:55506560,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同

其观点或证实其内容的真实性。