导语 本文主要是围绕android直播助手的功能做了一些研究,因为之前对Android多媒体相关的内容知之甚少,只有概念,于是查阅了相关资料并做以总结。

由于我对音视频相关知识零基础所以补充了一些相关知识

视音频编解码技术零基础学习方法

视音频数据处理入门:RGB、YUV像素数据处理

采集音频原始数据---->压缩编码----> 封装

采集视频原始数据---->压缩编码----> 封装

音视频编码

压缩编码就是对数据进行压缩以节省空间便于存储和传输。

视频压缩编码就是将视频帧的像素数据RGB或YUV等压缩成视频码流,编码一般对YUV格式进行,视频编码方案H.264,MPEG2,MPEG4等。

音频压缩编码就是将采样的音频采样数据PCM等压缩成音频码流。音频编码方案:AAC,WMA,MP3等。

编码是音视频技术中最重要的技术之一,也是难点,所幸的是,Android提供了MediaCodec用来方便开发者进行视音频的编解码,并且对于某种编码器还可以指定帧格式,尽管如此,我们也不能指定任意格式,因为这需要硬件的支持,可以通过API查询支持的帧格式。

通过createEncoderByType方法只需要传入mime即可创建对应的解码器,mime可以时下面的形式。

MediaCodec类的使用逻辑大致如下图所示,简单来说,一个编码器用于处理输入数据并对其进行编码处理后输出,它内部有一系列的输入和输出缓冲区,使用时,从编码器申请空的输入缓冲区,然后填充数据后发送给编码器处理,编码完成后编码器会将编码后的数据放入输出缓冲区,只需要从输出缓冲区取出编码后的数据后用于处理,最后将空间返还给编码器。

使用MediaCodec可以有三种方式

1. 使用Buffer数组的同步方式(API20以后deprecated)

2. 使用Buffer同步方式

3.异步方式

前两种方式基本类似,只是使用Buffer的同步方式性能更好。以第一种方式为例:

当要中指编码时只需要在最后一个有效数据Buffer中或者额外发送一个空的Buffer指定其Flag标志位为BUFFER_FLAG_END_OF_STREAM,然后调用queueInputBuffer发送给编码器即可。

除了直接使用ByteBuffer作为MediaCodec的输入输出还可以通过Surface作为数据的载体,具体的有两种:使用Input Surface和使用Output Surface。

以使用Input Surface为例,使用createInputSurface()方法创建一个Input Surface。

Requests a Surface to use as the input to an encoder, in place of input buffers.表明使用这个Surface来代替Buffer作为编码器的输入。

编码器将会自动的从Input Surface读取帧数据送往编码器。此时访问不到输入Buffer缓冲区,使用getInputBuffers等方法抛出异常。编码流结束时调用signalEndOfInputStream函数,该函数调用后,Surface就会停止向编码器提供数据流。

显然,这种方式在不需要获取音视频流的原始数据时是非常方便的。

音视频混合

封装一般指的是将进行过压缩编码的音频流和视频流进行合并,封装格式种类很多,例如MP4,MKV等等,它的作用就是将压缩编码的视频和音频按照一定的格式封装在一起。例如,将H.264编码的视频码流和AAC编码的音频码流合并成MP4格式的数据,

Android也提供了MediaMuxer支持将编码后的音视频码流合并成MP4格式的文件。

使用MediaMuxer的关键代码如下

Android5.0录制视频的方案

通过MediaProjectionManager进行录制屏幕。关键代码如下

在onActivityResult中判断是否获得录屏权限。然后执行下面操作。

createVirtualDisplay:Creates a VirtualDisplay to capture the contents of the screen

这个参数表示了录制的手机屏幕的内容要显示到哪个SurfaceView上,实际上表示了屏幕帧数据的走向,这个参数非常关键。

相关的几个类

ImageReader :The ImageReader class allows direct application access to image data rendered into a Surface

ImageReader类允许应用直接访问渲染到Surface上的image数据。使用MediaProjectionManager录制的屏幕内容可以直接渲染到一个Surface上,这个参数在createVirtualDisplay时传入,但是我们无法访问到渲染的内容。所以ImageReader类主要是用于使用Surface时访问不到原始视频数据流的情形。要想访问到每一帧的内容可以使用ImageReader类。

该类有一个函数getSurface获取一个Surface,通过这个函数获取一个Surface用来为ImageReader产生Images即视频流帧数据。

将这个Surface指定到录制屏幕时的Surface参数,就可以通过ImageReader读取到Surface上面渲染的每一帧的数据,通过acquireLatestImage()等方法可以获取一个Image对象。

Image:A single complete image buffer to use with a media source such as a MediaCodec or a CameraDevice.

也就是说Image类表示一个图片缓冲区,用来和MediaCodec一起使用。通过Image对象可以得到这一帧画面的像素数据,应该是RGB数据,转化为YUV格式的数据house,然后通过MediaCodec对其进行编码。

本地录屏方案

有了上面的准备知识,再来看直播助手的两个主要功能本地录屏和推流功能的实现逻辑容易多了。

本地录屏的逻辑:本地录屏不需要操作视频原始数据,因此使用Input Surface作为编码器的输入。

视频:MediaProjection通过createVirtualDisplay创建的VirtualDisplay传入的Surface是通过MediaCodec的createInputSurface方法返回的,表明编码器的输入其实来自于录制到的屏幕数据,于是只需要在MediaCodec的输出缓冲区中拿到编码后的ByteBuffer即可。

音频:录制程序获得音频原始数据PCM,传给MediaCodec编码,然后从MediaCodec的输出缓冲区拿到编码后的ByteBuffer即可。

最终通过合并模块将音视频混合。

推流的逻辑:推流SDK提供了一个编码器TVLiveSdk_LiveEncoder,它接受YUV420的视频数据格式和PCM编码的原始音频流。因此要获得视频的原始帧数据才行,可以通过ImageReader实现该功能。

视频:MediaProjection通过createVirtualDisplay创建的VirtualDisplay传入的Surface是通过ImageReader的getSurface方法返回的,表明录制的屏幕帧数据传递到ImageReader,于是通过ImageReader的相关API可以读取到录制的屏幕每一帧的数据,但这个数据时RGB格式的,转化为YUV格式后传到推流SDK即可。

音频:由于推流SDK需要的就是原始PCM编码的音频数据,因此录制到音频数据后直接调用推流SDK即可。

简单说就是重定向了屏幕录制的数据的方向,这个Surface提供的是什么,录制的视频数据就传到哪里。Surface提供的是本地某个SurfaceView控件,那么就会将屏幕内容显示到这个控件上,提供MediaCodec就是作为编码器的输入源最终获得编码后的数据,提供ImageReader就会作为ImageReader的数据源,最终获得了视频的原始数据流。

Android直播助手中录屏和推流具体框架设计

...

查看原文:http://qhyuang1992.com/index.php/2016/08/08/android5_0_lu_ping_fang_an/

转载于:https://www.cnblogs.com/qhyuan1992/p/6071974.html

Android5.0录屏方案相关推荐

  1. Android5.0录屏

    Android L新增了MediaProjection录屏的api,捣鼓了大半天,照着github上的demo撸了一遍代码,梳理梳理. 录屏实现依赖MediaProjectionManager 通过 ...

  2. android 5.0 录屏代码,Android5.0录屏

    Android L新增了MediaProjection录屏的api,捣鼓了大半天,照着github上的demo撸了一遍代码,梳理梳理. 录屏实现依赖MediaProjectionManager 经过 ...

  3. android 录屏方案 VFR和CFR

    android 5.0录屏的例子网上满天飞,我这里主要是总结一下,如何以VFR和CFR的方式来录屏.写这篇文章主要是因为我在做这个功能的过程中,在网上找了很久也没有找到一个固定帧率录屏的例子,后面还是 ...

  4. android 录屏自动运行,自动化录屏方案简介 for Android

    原标题:自动化录屏方案简介 for Android 前言 针对移动端项目的评测,为了记录并评估产品表现,时常需要对设备进行录屏以作后续分析. 那么,应该如何在Python脚本中可靠.可控地实现安卓设备 ...

  5. iOS安全之防止手机截屏/录屏导致泄密的方案: iOS11之后防止用户录屏方案、基于DRM防截屏/录屏 | 蓄力计划

    文章目录 前言 I.防止手机截屏泄密方案 1.1 应用被挂起时,在当前页面添加一层高斯模糊 1.2 监听收款码界面截图,对付款码进行高斯模糊,防止信息泄露 1.3 iOS11之后防止用户录屏方案 1. ...

  6. Android MediaProjection 录屏方案

    MediaProjection是Android5.0后提出的一套用于录制屏幕的API,无需root权限.与 MediaProjection协同的类有 MediaProjectionManager, M ...

  7. android 8.0 录屏命令,Android前置摄像头录制的视频介于7.5和8.0之间 – setVideoFrameRate不起作用 – 三星Galaxy S2...

    我正在尝试使用前置摄像头录制视频,以下是代码段,我将setVideoFrameRate设置为29,但是录制的视频的fps为7.5到8.我需要录制vidio的视频fps 29. recorder.set ...

  8. oCam_v520.0 录屏软件 资源下载

    有道云笔记http://note.youdao.com/noteshare?id=6379b8ddf60323479b68cc0d6e4e5c0a&sub=FB538535BAA9493397 ...

  9. 【Web技术】1159- 浅析 Web 录屏技术方案与实现

    前言 随着互联网技术飞速发展,网页录屏技术已趋于成熟.例如可将录屏技术运用到在线考试中,实现远程监考.屏幕共享以及录屏等:而在我们开发人员研发过程中,对于部分偶发事件,异常监控系统仅仅只能告知程序出错 ...

最新文章

  1. python 发布包_如何将自己的Python包发布到PyPI
  2. 利用Python在Jetson TX2上抓取和显示摄像头影像
  3. javaweb学习总结(三十一)——国际化(i18n)
  4. Java基础之扩展GUI——添加状态栏(Sketcher 1 with a status bar)
  5. angularjs的ng-repeat回调
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的学生请假管理系统
  7. 1.24 Java周末总结 ①乘法数据的溢出 ②测试random随机数几率是否相等 ③判断字符串是否为纯数字...
  8. 【报告分享】2020年中国金融科技企业领袖观点洞察报告.pdf(附下载链接)
  9. 20145335郝昊《网络对抗》逆向及Bof基础实践
  10. java判断是否为linux,java判断是否Linux操作系统,判断OS操作系统类型工具类
  11. Sofia-SIP辅助文档六 - Sofia-SIP中的SIP和SDP特性
  12. 学长教你买电脑(笔记本篇)
  13. 【电源干货】你的电源模块选对了吗?7招教会你!
  14. php yar 安装失败_全面解析php7安装yar扩展的方法
  15. curl 输出接口请求响应时间
  16. 仿淘宝商品界面(html div+css)
  17. jira任务导出excel
  18. 从中国金融的兴起,以后发展趋势变化分析
  19. 网络工程师成长日记309-西安李宁项目
  20. Memory Barriers

热门文章

  1. springboot使用jdbc连接mysql数据库
  2. 如何网络推广为你出招解决网站跳出率高问题!
  3. 特斯拉“刹车失灵”不绝于耳网络营销外包怎样看特斯拉进驻中国?
  4. 浅析面包屑导航对网站SEO优化有哪些作用?
  5. B2B平台推广技巧让网络营销更上一个台阶!
  6. python pycurl_简单谈谈Python的pycurl模块_python
  7. mysql可以运行计时_mysql的event schedule 计时执行
  8. python勾股定理_Python学习第128课——在Python中实现醉汉随机游走
  9. android使用java library module时初始化OkHttpClient时报错 ClassDefNotFoundError之类的
  10. 江西鹰潭、江西移动与华为战略合作:共推物联网——物联网的世界要到来了...