分析桌面屏幕视频数据源的功能
优采云 发布时间: 2020-08-08 04:50I. 前言
以前在Android实时视频中介绍了一种视频源数据采集: 摄像机视频数据采集和分析介绍了使用摄像机的回调机制来获取摄像机数据的每一帧,然后执行流的二次处理. 现在,我们介绍另一种视频源,即屏幕桌面视频数据源. 这是屏幕录制功能. 在这个阶段,Android中还有许多用例. 例如,录制游戏时使用了诸如斗鱼之类的实时应用程序. 还有很多,因为当今手机游戏如此流行,并且游戏视频实时流媒体也是一个很好的行业!
第二个技术解决方案
首先让我们分析一下在Android屏幕录制中使用了哪些方案?目前,在Android屏幕录制中大约有两个选项:
1. 在Android 5.0下,获取root权限并使用adb shell screenrecord命令功能进行记录
2. 在Android5.0以上版本中,使用系统Api函数: MediaProjection和VirtualDisplay
实际上,这两种方法的底层实现机制是相同的,因为在5.0之前,Google可能有记录屏幕功能的一定风险,因此此功能尚未打开,但我不知道为什么5.0是开放的,当然,一旦打开,就会立即创建一个漏洞,将在下一篇文章中介绍. 从安全角度考虑,不应公开屏幕捕获和记录功能,因为该功能太危险了. 据报道,某个APP使用此功能在后台记录屏幕,然后将其传递给服务器. 然后,当用户输入全部记录了帐户信息时,存在很大的风险.
三,使用命令功能录制视频
我们首先介绍Android5.0屏幕录制功能.
在Android中,拍摄屏幕快照时可以使用adb shell screencap命令,而在录制视频时可以使用adb shell screenrecord. 首先让我们看一下此命令的用法:
(1),基本用途
录制默认分辨率,默认4Mbps,默认180s视频,并将其保存到名为FILENAME.mp4的sdcard
$ adb shell screenrecord /sdcard/FILENAME.mp4
(2),指定分辨率(参数: --size)
//分辨率为112x112,建议不要指定分辨率,最好使用默认分辨率
$ adb shell screenrecord --size 112x112 /sdcard/FILENAME.mp4
注意: 分辨率不能完全自定义. 例如,在我的手机上录制100x100时,会提示错误:
$ adb shell screenrecord --size 100x100 /sdcard/FILENAME.mp4
(3),指定比特率(参数: --bit-rate)
将比特率设置为8Mbps. 比特率越大,文件越大,图片越清晰.
$ adb shell屏幕记录-比特率8000000 /sdcard/FILENAME.mp4
(4),旋转(参数: --rotate)
旋转90度
$ adb shell屏幕记录--rotate /sdcard/FILENAME.mp4
注意: 不支持声音. 如有必要,请单独记录. 此命令要求使用root特权,这也非常有限!
让我们看一下以下情况:
使用adb shell screenrecord /sdcard/capture.mp4命令录制视频并将其保存到SD卡,然后使用adb pull将其本地导出.
看看效果:
我们可以看到该功能,并且可以发现该功能实际上用于测试. 在测试时,有时很难重现复杂的测试方案. 您可以使用屏幕录制功能来查找问题.
现在,如果应用程序具有root功能,它将开始在后台秘密录制视频,然后将录制的视频文件发送到服务器进行分析,这非常危险.
尽管可以使用此功能,但我们发现在直播期间,如何获取数据流并将其推送到服务器?因为当采集并推送视频时,会获得视频流数据,并且在底层使用rtmp打包数据并将其发送到服务器,所以这里有些人会怀疑他们是否可以将视频记录到本地文件中然后同时读取文件. 流字节,推流?实际上,这个主意很好,但是我没有那样做,因为效率问题,其次是文件读写异步问题,这是一个主意,看一下adb screenrecord命令的源代码,因为它最终会将采样的数据写入本地文件,所以我们可以在此之前获得视频流,但这不是本文的重点,因为如果引入此内容,将会太多,并且随着Android系统的改进,未来将被更多使用. Android系统是更高版本,因此引入5.0中添加的MediaProjection类以进行屏幕记录非常重要.
四,使用打开的Api录制视频
Android 5.0已添加了一组用于屏幕记录的API,MediaProjection + VirtualDiaplay. 用法也很简单. 您需要先申请许可,然后才能使用它!
首先,介绍使用过程
让我们看一下下面的使用过程:
1》使用getSystemService(Context.MEDIA_PROJECTION_SERVICE)方法获取MediaProjectionManager对象
2“打开授权意图: startActivityForResult(mProjectionManager.createScreenCaptureIntent(),PERMISSION_CODE);
3“,在onActivityResult方法中处理授权后:
我在这里看到,使用返回的resultCode和数据数据来获取MediaProjection对象,注册一个回调接口,该接口用于监视记录状态信息,并最终创建VirtualDisplay
4》创建VirtualDisplay虚拟屏幕
参数说明:
*第一个参数: 虚拟屏幕名称
*第二个参数: 虚拟屏幕的宽度
*第三个参数: 虚拟屏幕的高度
*第四个参数: 虚拟屏幕的徽标
*第五个参数: 虚拟屏幕输出的表面
*第六个参数: 虚拟屏幕回调界面
最重要的参数是第五个参数,输出记录屏幕. 他正在介绍Surface类型. 如果要在录制后引入视频数据,则需要创建一个Surface类型. 这里有三种创建Surface类型的方法:
1》如果要截屏,可以使用ImageReader类的getSurface方法获取
2》如果要录制视频进行编码,可以使用MediaRecorder类的getSurface方法获取
3“最后,如果要录制视频进行编码并获取视频流,请使用MediaCodec的createInputSurface方法获取它
我们首先介绍前两个功能,然后将详细介绍以下功能!
第二,屏幕截图功能简介
首先让我们看一下屏幕截图功能. 实际上,在Android中基本上可以通过三种方式来截取屏幕截图:
第一个使用adb shell screencap命令,但需要root特权
第二种方法是使用getWindow(). getDecorView()获取当前“活动”页面的“查看”数据,然后保存位图,但是此方法有局限性. 一个是他只能截取当前应用程序的图像,而截取的图片不包括状态栏.
第三种方法使用MediaProjection和ImageReader截屏
让我们详细介绍如何使用MediaProjection截屏
首先声明一个ImageReader类,参数相对简单,但应注意,其大小,高度和宽度必须与以下相同以创建VirtualDisplay:
然后将ImageReader的getSurface设置为屏幕的输出. 接下来,开始截图:
从ImageReader获取Image对象,然后获取图片字节数据,并生成位图.
让我们看一下效果:
状态栏也在这里成功拦截!到目前为止,已实现MediaProjection的第一个功能以实现屏幕截图功能.
第三,屏幕录像功能介绍
在这里,我们首先使用MediaRecorder类进行数据编码. 如果我们确实要推送流,则需要使用MediaCodec,因为我们需要获取编码的视频流数据,而MediaRecorder不能这样做,但是本文仅介绍记录功能,下一篇将介绍MediaCodec功能详细!
使用MediaRecorder类非常简单,它与稍后介绍的MediaCodec相同. 首先是初始化编码器的参数信息,这些参数信息为:
视频大小,视频帧频,视频采样率(比特率),视频编码格式等
但是MediaRecorder还需要其他一些设置,例如设置视频源. 这里一般有两个来源,一个是相机,另一个是Surface类型,另一个是视频输出格式,以及视频输出文件路径,当然MediaRecorder也支持音频录制,并且参数设置类似于那些视频:
以下是一些默认的格式参数选择:
视频编码格式: 默认,H263,H264,MPEG_4_SP
获取视频资源: 默认,摄像机
音频编码格式: 默认,AAC,AMR_NB,AMR_WB
获取音频资源: 默认,*敏*感*词*摄像机,麦克风,语音通话,语音通信,语音下行链路,语音识别,语音上行链路
输出方法: amr_nb,amr_wb,默认,mpeg_4,raw_amr,three_gpp
初始化MediaRecorder后,您需要调用prepare方法进行准备. 如果您不再次调用getSurface,则会报告错误:
调用此方法时,我总是遇到此错误. 通常的原因是,必须在prepare方法和stop方法之间调用此方法,或者视频源必须是Surface类型. 让我们看一下VirtualDisplay类的创建:
调用getSurface方法以获取VirtualDisplay的输出屏幕. 然后,您需要调用开始编码方法start.
让我们看一下效果:
首先,您需要对系统进行授权. 单击立即开始以开始记录和编码. 在这里,将编码文件保存到SD. 我们正在使用adb pull命令进行导出. 该效果将不在此处显示. adb shell screenrecord命令具有相同的效果!
五个. 技术概述
1. 引入了adb shell screenrecord命令来录制视频,但是有一个限制,需要root权限
2. 引入了MediaProjection + ImageReader类的屏幕截图功能
3. 引入了用于视频录制功能的MediaProjection + MediaRecorder类
六. 旧版问题
使用MediaProjection和MediaRecorder录制视频,或将命令录制保存到本地文件,但是在实际流传输过程中需要获取视频流数据,因此此方法不适用于后续的流媒体工作. 一篇文章将介绍MediaCodec如何执行视频编码. 该编码类可以获取编码后的视频流数据.
七. 摘要
Android在5.0之后发布了用于屏幕记录功能的api,但是其安全性仍然值得考虑. 后续文章将详细介绍MediaProjection中的一个漏洞,该漏洞可能导致用户的屏幕操作信息泄漏. 如果信息泄漏,则意味着用户的帐户信息面临很大的风险. 但是,由于有API,因此今年是直播的一年. 在唱片游戏行业中,此功能也很重要!