对于安卓而言录屏有两套方案:

1,在Android app层使用MediaProjection框架。这个方案网上有很多资料,参考案例

优点:实现原型快/稳定。缺点:对性能要有进一步提升的厂家来说可能不太适合了。

 

2,在Android native层使用DisplayProjection框架。这个方案Android源码自带,不过网上关于它的资料少。

位于安卓的路径:frameworks/av/cmds/screenrecord/。本人改进的源码:https://github.com/Mr-jinfa/android-screen-and-push-h264

优点:代码执行位于Android native层,执行快/维护性高。缺点:调试难度较大。


    简述: 

    上面描述的两套方案工作时均验证过。验证的结果是:方案二更轻巧、快捷、绕过MediaProjectionManager 权限管理。

可以插件.so的形式整合到其它大型系统。

    关于MediaProjectionManager 权限管理有一个坑:之前开发经验,当自身程序调用startActivityForResult向MediaProjectionManager申请权限时有时候会申请不到。

    原因是在startActivityForResult等待MediaProjectionManager的onActivityResult时自身程序由于anr或其它原因被系统kill。当系统拉活自身程序后再次申请却再也申请不到。

所以,我采用了方案二。下面我简单地分析下安卓自带的screenrecord源码并做相应的改良。

    程序的主逻辑:

    该程序采用主从线程机制,主线程负责初始化peer端连接、初始化录屏、编码器,横竖屏切换命令,loop读取编码器输出的raw h264。从线程负责往peer端推raw h264流。

    网络结构:

采用tcp协议监听一端口并复用两通道机制(accept两个连接)

通道1:命令通道

通道2:raw h264流通道

Android SplashScreen支持视频 screenstream安卓_Android

 

    安卓自带screenrecord工具录屏、编码机制

Android SplashScreen支持视频 screenstream安卓_竖屏_02

    横竖屏切换的逻辑:系统默认竖屏,当横屏时主屏分辨率不变,渲染的内容顺时针旋转90度。注意了,旋转过后坐标系会改变!坐标系原点从原来的左上角变为右上角。所以虚屏那边需要和主屏同步也要顺时针旋转90度。具体可以参考runEncoder-->case NO_ERROR:-->else if (orientation != mainDpyInfo.orientation)执行路径上下文源码。

    程序主体结构

Android SplashScreen支持视频 screenstream安卓_竖屏_03

    需要说明的是:我的博客很少直接贴源码并直接分析源码。因为我认为,当我们知道需求、实现的大概逻辑、程序主体结构后。分析源码就是砍瓜切菜的事情。。

    所以,读者通过了解上面3张图示,结合代码应该很容易知道录屏、编码、推流过程。我提供的源码/测试源码也有相关的解析。有兴趣的同学可以clone下来了解一下。。