朱金波

网易资深开发工程师

2010年开始从事Android开发工作

有着丰富的Android开发经验

作者简介

在Android上要实现一个录制功能,需要有几个方面的知识储备:自定义相机的开发、视频数据格式的了解、编码相关知识以及视频合成技术,同时如果需要美颜、磨皮等滤镜操作还需要一定的openGL的知识。如果有需要深入音视频方面开发的同学建议先了解下上述的基本知识点。

既然要实现720P、30帧 同时又要对视频数据进行滤镜处理的录制,那我们首先就要确定一个正确的实现方案。如果方案选错了,那即使实现了录制功能,但性能达不到30帧或是CPU消耗太大手机发烫那就不好了。

视频的编码录制主要是软编和硬编两种方案:

  • 软编即采用CPU对相机采集的原始数据进行编码后再和音频一起合并成一个MP4等格式的文件。优点 是技术相对成熟,网上开源的编码以及合成库很多,实现相对较快,同时兼容性比较好。缺点 是CPU暂用率高,性能差的手机无法达到720P的30帧,同时引用了大量的第三方库,导致包很大。

软编的具体实现方案如下图所示,流程相对清晰简单:

  • 硬编即采用手机提供的硬编接口,利用硬件芯片直接进行编码合成。优点 是速度快、效率高、CPU占用极少,即使长时间高清录制也不会发烫,同时由于使用系统API,库相对较小。缺点 是某些奇葩机型需要处理兼容性问题,同时Android上的硬编跟Surface以及openGL关系比较密切,网上相关知识较少,需要自己摸索踩坑。

硬编的主要流程如下图所示,可以看到所有的数据,从采集、编码、显示以及合成都在GPU里面进行流转。

结合上面分析的两种方案我们可以看到,在Android这类移动平台上,使用第二种硬编的方式是比较合适的。由于短视频的本地录制不像直播等场景对带宽的要求比较大,需要动态调节编码器码率帧率的情况,本地录制可以将编码器的码率设置的比较高,也不需要动态改变分辨率。因此采用硬件编码的方式既可以省CPU的性能又可以实现720P的高效编码。

确定了方案之后,我们就着重讲一下硬编方案的各个步骤的实现方式。

自定义相机的开发

我们知道根据Android的系统Camera API,可以通过setPreviewDisplay接口给Camera设置一个SurfaceView的SurfaceHolder就可以让Camera采集的数据显示到SurfaceView上了。这个接口的好处是系统帮我们处理了相机采集的各种角度同时进行了绘制,如果只是简单的录制可以这么使用,但我们需要对相机采集的数据进行滤镜处理,那这个接口就不合适了。

因此我们需要用到另外一个接口 setPreviewTexture:

通过给Camera设置一个SurfaceTexture,可以将Camera采集的数据先映射到这个SurfaceTexture上,然后我们根据创建这个SurfaceTexture的TextureID来获取GPU上的Camera数据

滤镜以及本地绘制

我们通过SurfaceTexture绑定的TextureID可以获取到Camer采集到GPU上的视频数据。然后可以将TextureID送给一些第三方滤镜库进行美颜滤镜或是自己编写Shader进行磨皮和美白。自己编写Shader需要opengl以及图像算法方面的知识,通常需要专门的开发人员,这里就不做详细的展开了(当然最简单的就是接入网易云短视频SDK了,里面实现了磨皮、美颜和多款滤镜)。

本地绘制主要靠opengl进行绘制,我们需要先在Camera的采集回调线程上创建一个EGLContext以及EGLDisplay和EGLSurface, 其中EGLContext是opengl在该线程上的上下文,EGLDisplay是一块GPU中的虚拟显示区,主要用于缓存GPU上的视频数据,EGLSurface为具体显示的View到opengl上的映射,是真正绘制到View上的工具。当接受到Camera采集回调的一帧数据后,我们先通过SurfaceTexture.updateTexImage()方法,将Camera采集的数据映射到SurfaceTexture。然后根据glsl语言将TextureID对应的数据绘制到EGLDisplay上,这里需要注意的是,Camera采集是有角度的,横竖屏下角度不同,可以通过SurfaceTexture的getTransformMatrix方法获取角度矩阵,然后把矩阵传给EGLDisplay进行旋转。EGLDisplay旋转绘制完成后通过eglSwapBuffers方法就可以将EGLDisplay上的数据拷贝到EGLSurface上进行显示了。Android 系统中的GLSurfaceView最后就是通过eglSwapBuffers将数据显示到我们看到的屏幕上的。

硬件编码

Android上的硬件编码主要靠MediaCodeC API实现的,下面是MediaCodeC比较经典的一张数据处理图

从图中我们看到,MediaCodeC主要处理流程就是:

·       创建并配置一个 MediaCodec 对象

·       循环直到完成:
如果输入缓冲区就绪,读取一个输入块,并复制到输入缓冲区中
如果输出缓冲区就绪,复制输出缓冲区的数据

·       释放 MediaCodec 对象

从Android的官方文档我们看到,MediaCodeC支持ByteBuffers和Surface两种输入方式,文档也指明了Surface方式可以提高编码效率,而且我们上面的Camera数据也是采集到的SurfaceTexture,因此我们这里使用Surface方式作为输入源。

我们在上面显示部分提到EGLSurface是作为真正输出显示的模块,MediaCodec也是。我们先通过MediaCodec创建一个Surface,然后将这个Surface绑定到一个EGLSurface,当Camera采集的数据回调时,我们只要重复一次绘制模块的操作,将Camera采集到SurfaceTexture上的数据swapBuffers到EGLSurface 上就可以了。然后循环MediaCodec输出缓冲区,MediaCodec就会将编码后的数据返回给我们了。这样做的好处就是将显示和编码完全分离了,即使我们没有UI View的情况下也可以进行编码,比如在不同Activity之间切换也不会影响我们的正常编码。

视频合成

Android上视频合成主要通过MediaMuxer API实现。MediaMuxer类相对比较简单,特别是配合MediaCodec使用。 我们只需要通过 addTrack 来添加视频和音频通道接口。AddTrack 接口需要传入一个MediaFormat对象,MediaFormat即媒体格式类,用于描述媒体的格式参数,如视频帧率、音频采样率等。还好我们使用了MediaCodeC,MediaCodeC会返回MediaFormat给我们,如果是使用软编然后用MediaMuxer进行合并的话,这里有一个比较大的坑,如果手动创建MediaFormat对象的话,一定要记得设置"csd-0"和"csd-1"这两个参数:其中"csd-0"和"csd-1"对应的是视频的sps和pps,对于AAC音频的话,对应的是ADTS。不设置的话会崩溃的。 设置完这些之后,只要编码器来一帧数据,我们送到MediaMuxer中可以出来MP4了。

最后大体的流程图就是:

网易云短视频SDK按照上述方案实现后的效果就是:720P、30帧,磨皮、美颜滤镜全开的情况下,市面上的绝大部分手机都可以达到这个效果,连一些Android 4.3系统的老爷机也可以,而且CPU占用才4~5%,录制一小时也感觉不到手机发烫

Android短视频中如何实现720P磨皮美颜录制相关推荐

  1. Android短视频中如何实现720P磨皮美颜录制?

    视频中磨皮.美颜功能已成为刚需,那么如何在Android短视频中实现720P磨皮美颜录制?本篇文章中,网易云信资深开发工程师将向大家介绍具体的操作方法. 相关阅读推荐 <短视频技术详解:Andr ...

  2. android 视频美颜,Android短视频中如何实现720P磨皮美颜录制?

    视频中磨皮.美颜功能已成为刚需,那么如何在Android短视频中实现720P磨皮美颜录制?本篇文章中,网易云信资深开发工程师将向大家介绍具体的操作方法. 相关阅读推荐 在Android上要实现一个录制 ...

  3. android opengl美颜功能,Android短视频中如何实现720P磨皮美颜录制

    在Android上要实现一个录制功能,需要有几个方面的知识储备:自定义相机的开发.视频数据格式的了解.编码相关知识以及视频合成技术,同时如果需要美颜.磨皮等滤镜操作还需要一定的openGL的知识.如果 ...

  4. 短视频软件开发中如何实现720P磨皮美颜录制?

    短视频软件开发中如何实现720P磨皮美颜录制? 在Android上要实现一个录制功能,需要有几个方面的知识储备:自定义相机的开发.视频数据格式的了解.编码相关知识以及视频合成技术,同时如果需要美颜.磨 ...

  5. Android短视频开发中的sdk接入方案

    目前短视频平台非常火,云豹科技作为优质的app源码提供商,在短视频开发领域有丰富的经验和完善的技术.下面以云豹短视频为例,概述Android短视频开发中的sdk接入方案,这里我们选择腾讯云的sdk进行 ...

  6. Android短视频开发都需要什么技术?

    今天我们来讲点干货,估计来看这篇帖子的人都知道短视频APP有多火,也都知道安卓系统在手机系统中占的市场份额有多大,那我就不多嘴巴拉巴拉一些行业背景了,以下我着重讲一讲Android端的短视频开发技术. ...

  7. android短视频技术,Android短视频开发都需要什么技术?

    今天我们来讲点干货,估计来看这篇帖子的人都知道短视频APP有多火,也都知道安卓系统在手机系统中占的市场份额有多大,那我就不多嘴巴拉巴拉一些行业背景了,以下我着重讲一讲Android端的短视频开发技术. ...

  8. Android 短视频编辑开发之摄像头预览实时美颜(三)

    前言: 在上一篇文章中给小伙伴们介绍了进行Camera预览,如果你还没有看过的话,建议先去看上一篇文章<Android 短视频开发之摄像头预览(二> 本篇文章会介绍如何实现摄像头预览画面实 ...

  9. android 短视频例子,Android短视频开发解析,什么才是开发的重点

    随着短视频的潮流席卷祖国大地,进行Android短视频开发的朋友们也越来越多了,相信很多朋友在进行短视频开发.平台搭建的时候会有点蒙,短视频这么多功能,哪个是重点呀? 接下来就为大家讲解一下,Andr ...

最新文章

  1. authc过滤器 shiro_Shiro的web下的使用
  2. ‘shared_ptr‘ is not a member of ‘std’
  3. C++ 命名空间 实战(一)嵌套的命名空间
  4. 走,去谷歌的机房逛逛
  5. 用python定义一个员工类_Python:定义一个只有整数定义的类
  6. 给定数组 求和等于固定值 算法_别人家的面试题:不可变数组快速范围求和
  7. angularjs文档下载
  8. mysql数据库表迁移
  9. 乙肝疫苗该怎么打(转)
  10. 中石油训练赛 - 位置(模拟+思维)
  11. java基础题 解析_Java基础面试题及答案解析(10)
  12. mac系统更新后code .命令打不开vs code
  13. Java 8 Friday:不再需要ORM
  14. Music Game
  15. C++bitset二进制有序集
  16. knn算法python代码识别手写数字_python使用KNN算法识别手写数字
  17. C++basic_string(字符串类模板)
  18. pdf转word思路和方法
  19. 继承QPushButton重写MouseEvent后按钮clicked信号不响应
  20. 投影仪与计算机连接方式,【投影网教程】投影仪连接电脑的方法

热门文章

  1. data structure begin!!
  2. 学渣笔记之矩阵的导数与迹
  3. c字符串函数实现(1)---strncpy
  4. 谈谈我对Java中CallBack的理解
  5. 关闭 VSCode 自动更新
  6. Uedit32安装教程附安装包资源
  7. SCI论文写作--工科学生如何入门搞科研和写作
  8. bitmap xml大小 安卓_一张壁纸让安卓用户手机系统崩溃,包括三星、小米、一加等...
  9. java如何打logo,利用java给网站图片打上文本或图片logo
  10. python精要(66)—类(3)-文档字符串,注释文档