Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

时间:2021-09-16 13:14:48

一、前言

之前介绍了Android直播视频中一种视频源数据采集:摄像头Camera视频数据采集分析 中介绍了利用Camera的回调机制,获取摄像头的每一帧数据,然后进行二次处理进行推流。现在我们在介绍另外一种视频源类型,屏幕桌面视频数据源,这个就是录屏功能,这个在Android中的利用场景现阶段也是很多的,比如像斗鱼这些直播app,在录制游戏的时候用的还是比较多的,因为现在的移动游戏也那么火,游戏视频直播也是一个很不错的产业!

二、技术方案

下面先来分析一下Android中录制屏幕采用的方案有哪些?现阶段Android中录制屏幕的话大致就两种方案:

1、Android5.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,先来看看这个命令的用法:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

(1)、基本使用
录制默认分辨率,默认4Mbps,默认180s的视频,保存到sdcard上名为FILENAME.mp4
$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 screenrecord --bit-rate 8000000 /sdcard/FILENAME.mp4

(4)、旋转(参数:--rotate)
旋转90度
$adb shell screenrecord --rotate /sdcard/FILENAME.mp4

注意:
不支持声音,如有需要,另外独立录制。此命令需要root权限才可以使用,这个也是已非常大的局限性!

下面来看一下案例:

使用adb shell screenrecord /sdcard/capture.mp4 命令录制视频存到SD卡中,然后在使用adb pull导出到本地即可

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

看看效果:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

功能我们可以看到了,可以发现其实这个功能测试用的比较多,他们在测试的时候,有时候复杂的测试场景难以重现,就可以使用录制屏幕功能,来跟踪问题。

那么现在如果一个应用获取到了root功能,就开始偷偷的在后台录制视频,然后把录制之后的视频文件发到服务端,然后进行分析,那么是非常危险的。

虽然这个功能可以了,但是我们发现,在直播的时候,如何进行数据流采取然后推流到服务端呢?因为在视频采集推流的时候,都是获取视频流数据,在底层使用rtmp进行数据打包发送服务端,那么这里有人会想,能不能一边录制视频到本地文件,然后一边在去读取这个文件流字节,进行推流?其实这种想法是好的,但是没有那么做的,因为这效率问题,其次是文件读写不同步问题,这里有一个思路就是,看看adb screenrecord命令的源码了,因为他最终是采样数据写到本地文件的,那么在这个之前我们可以进行获取视频流即可,但是这个不是本文的重点,因为这个要是介绍的话,那就太多了,而且随着Android系统提升,未来用的多的是Android系统更高版本,所以这里要注重介绍的是5.0加的MediaProjection类来进行屏幕录制。

四、使用开放Api进行录制视频

Android5.0中添加了一套Api来进行屏幕录制功能,就是MediaProjection+VirtualDiaplay,用法也是非常简单的,在使用之前需要申请一下权限,然后获取权限之后,就开始使用即可!

第一、使用流程介绍

下面来看看使用流程:

1》使用getSystemService(Context.MEDIA_PROJECTION_SERVICE)方法获取MediaProjectionManager对象

2》开启授权Intent:startActivityForResult(mProjectionManager.createScreenCaptureIntent(),PERMISSION_CODE);

3》授权之后在onActivityResult方法中进行处理:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

这里看到了,利用返回的resultCode和data数据,得到MediaProjection对象,在注册一个回调接口,这个接口就是监听录制的状态信息,最后在创建一个VirtualDisplay

4》创建VirtualDisplay虚拟画面

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

参数说明:

* 第一个参数:虚拟画面名称
* 第二个参数:虚拟画面的宽度
* 第三个参数:虚拟画面的高度
* 第四个参数:虚拟画面的标志
* 第五个参数:虚拟画面输出的Surface
* 第六个参数:虚拟画面回调接口

其中最重要的就是第五个参数,录制画面输出的地方,他这里介绍的是一个Surface类型,那么我们如果想介绍录制之后的视频数据,就需要创建一个Surface类型即可。在这里有三个方式创建Surface类型:

1》如果想截屏,那么可以使用ImageReader类的getSurface方法获取

2》如果想录制视频进行编码,可以使用MediaRecorder类的getSurface方法获取

3》最后如果想录制视频进行编码,并且获取视频流的话,使用MediaCodec的createInputSurface方法获取

这里我们先介绍前面两个功能,后续的那个功能再详细介绍!

第二、截图功能介绍

先来看看截图功能,其实在Android中截图大体上就三种方式:

第一种使用adb shell screencap命令,但是需要root权限

第二种使用getWindow().getDecorView()获取当前Activity页面的View数据,然后进行保存Bitmap,但是这种方式有限制,一个是他只能截取当前应用的图,而且截取的图片不包括状态栏。

第三种使用MediaProjection和ImageReader来进行截图

下面就来详细介绍如何使用MediaProjection来进行截图

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

先声明一个ImageReader类,参数比较简单,不过要注意的是这里的尺寸高宽要和下面创建VirtualDisplay一直:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

然后把ImageReader的getSurface设置成画面的输出即可。接下来就开始截图:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

从ImageReader中获取Image对象,然后得到图片字节数据,生成一个Bitmap即可。

下面来看看效果:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

这里把状态栏也成功截取了!到这里就实现了MediaProjection的第一个功能实现屏幕截图功能。

第三、屏幕录制功能介绍

这里先使用MediaRecorder类进行数据的编码工作,而我们真正要进行推流的话需要使用MediaCodec,因为我们需要获取到编码之后的视频流数据,而MediaRecorder是做不到这点的,但是本文只是先介绍录制功能,下一篇文章在详细介绍MediaCodec类功能!

使用MediaRecorder类很简单,以及后面介绍MediaCodec都一样,首先是初始化设置编码器的参数信息,而这些参数信息就那些:

视频尺寸高宽、视频帧率,视频采样率(码率),视频编码格式等

但是MediaRecorder还需要一些其他设置,比如设置视频来源,这里一般就两个来源,一个是摄像头Camera,一个是Surface类型,还有就是视频的输出格式,以及视频的输出文件路径等,当然MediaRecorder还支持音频录制,参数设置和视频差不多:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

这里有一些默认格式参数选择:

视频编码格式:default,H263,H264,MPEG_4_SP
获得视频资源:default,CAMERA
音频编码格式:default,AAC,AMR_NB,AMR_WB
获得音频资源:defalut,camcorder,mic,voice_call,voice_communication,voice_downlink,voice_recognition, voice_uplink
输出方式:amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp

初始化完了MediaRecorder之后,需要在调用prepare方法做准备,不然后续再调用getSurface会报错的:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

在调用这个方法的时候总是遇到这种错误,大致原因就是这个方法必须在prepare方法和stop方法中间调用,或者是视频源必须是Surface类型的。下面再来看看创建VirtualDisplay类:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

调用getSurface方法获取到VirtualDisplay的输出画面。然后就需要调用开始编码方法start即可。

下面来看一下效果:

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析

首先先需要系统进行授权,点击立即开始,就开始录制编码了,这里把编码之后的文件保存到sd中,我们在使用adb pull命令导出来,效果这里就不演示了,和上面的adb shell screenrecord命令产生的效果一样!

项目下载:http://download.csdn.net/detail/jiangwei0910410003/9596624

五、技术概要

1、介绍adb shell screenrecord命令录制视频,但是有局限性就是需要root权限

2、介绍了MediaProjection+ImageReader类进行截图功能

3、介绍了MediaProjection+MediaRecorder类进行视频录制功能

六、遗留问题

采用MediaProjection和MediaRecorder录制视频,或者是命令录制都是保存到本地文件了,但是在真正推流的过程中需要获取到视频流数据,所以这种方式不适合后续的推流工作,下一篇文章就要介绍如何MediaCodec进行视频编码,这个编码类是可以获取到编码之后的视频流数据的。

七、总结

Android中在5.0之后放出了录制屏幕功能的api,但是其安全性还是值得考虑的,后续一篇文章就详细介绍一个关于MediaProjection的漏洞,导致用户的屏幕操作信息可能被泄露,而这些信息被泄露那么就代表这用户的账号信息存在很大的风险,但是既然有着api了,那么今年又是直播年,在录制游戏这个产业中,这个功能也是无可厚非的重要!

Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析的更多相关文章

  1. Android中直播视频技术探究之---摄像头Camera视频源数据采集解析

    一.前言 在视频直播中一般都是两种视频数据源,一个是摄像头数据,一个是录制桌面数据,而一般来说美女妹子直播都是来自于摄像头数据,游戏直播都是录制桌面数据的,那么今天就来看看第一个数据源数据采集分析,A ...

  2. Android中直播视频技术探究之---基础知识大纲介绍

    一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更 ...

  3. Android中Java反射技术的使用示例

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  4. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  5. Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)

    原文:Android菜鸟的成长笔记(15)-- Android中的状态保存探究(下) 在上一篇中我们简单了解关于Android中状态保存的过程和原理,这一篇中我们来看一下在系统配置改变的情况下保存数据 ...

  6. Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+RTMP)

    一.前言 前面介绍了Android中视频直播中的一个重要类ByteBuffer,不了解的同学可以 点击查看 到这里开始,我们开始动手开发了,因为我们后续肯定是需要直播视频功能,然后把视频推流到服务端, ...

  7. Android中直播视频技术探究之---采集摄像头Camera视频源数据进行推流(采用金山云SDK)

    一.前言 在之前已经详细介绍了Android中的一种视频数据源:Camera,不了解的同学可以点击进入:Android中Camera使用详解 ,在这篇文章中我们介绍了如何采集摄像头的每一帧数据,然后进 ...

  8. 6、Android中的NFC技术

    Android对NFC技术的支持 Android2.3.1(API Level = 9)开始支持NFC技术,但Android2.x和Android3.x对NFC的支持非常有限.而从Android4.0 ...

  9. Android 中使用MediaRecorder进行录像详解(视频录制)

    在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. package com.video; import java.io.IOException; import android.ap ...

随机推荐

  1. jsp回车键登录代码

    $("body").keydown(function(event) { if (event.keyCode == "13") {// keyCode=13是回车 ...

  2. UVa 11292 The Dragon of Loowater 勇者斗恶龙

    你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(也就是砍掉所有的头).村里有m个骑士可以雇佣,一个能力值为 x 的骑士可以砍掉恶龙一个直径不超过 x 的头,且需要支付 x 个金币.如何雇佣骑 ...

  3. 使用DataContractJsonSerializer类将类型实例序列化为JSON字符串和反序列化为实例对象 分类: JSON 前端 2014-11-10 10:20 97人阅读 评论(1) 收藏

    一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...

  4. HDU-2059龟兔赛跑(基础方程DP-遍历之前的所有状态)

    Problem Description 据说在很久很久以前,可怜的兔子经历了人生中最大的打击——赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成了绝技,能 ...

  5. 客户调查(client)

    客户调查(client) 题目描述 公司派你去和几位客户面谈,以了解他们对公司产品的意见.你逐个打电话与客户联系,得知他们一般都很忙,不过他们还是可以为你抽出一点时间.现在的问题是有些客户的时间有冲突 ...

  6. 关于EF+MVC5分页查询数据效率问题

    2017-03-31 11:57:41,290 [5] ERROR ErrorMsg - System.Data.Entity.Core.EntityCommandExecutionException ...

  7. 如何反编译APK?

    1.概述 一些商业的app都包含很多精美的图片还有一些比较好的配置文件,以前某师兄就说过apk把后缀改为zip,然后解压一下就可以获得很多图片资源,但是这时候你打开一下解压出来的xml资源全是乱码.通 ...

  8. 微信小程序:java后台获取openId

    一.功能描述 openId是某个微信账户对应某个小程序或者公众号的唯一标识,但openId必须经过后台解密才能获取(之前实现过前台解密,可是由于微信小程序的种种限制,前台解密无法在小程序发布后使用) ...

  9. servlet常用操作

      servlet常用操作 CreateTime--2017年9月7日09:36:43 Author:Marydon 1.获取当前应用程序对象 需要导入: import javax.servlet.S ...

  10. Qt Quick程序的发布

    要将程序发布出去,首先需要使用release方式编译程序,然后将生成的.exe可执行文件和需要的库文件发在一起打包进行发布. 要确定需要哪些动态库文件,可以直接双击.exe文件,提示缺少那个dll文件 ...