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

相关阅读推荐

短视频技术详解: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可以获取到Camera采集到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主要处理流程就是:

l  创建并配置一个 MediaCodec 对象

l  循环直到完成:

如果输入缓冲区就绪,读取一个输入块,并复制到输入缓冲区中

如果输出缓冲区就绪,复制输出缓冲区的数据

l  释放 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了。

最后大体的流程图就是:

以上就是在Android短视频中实现720P磨皮美颜录制的分享。

另外,想要获取更多产品干货、技术干货,记得关注网易云信博客

Android短视频中如何实现720P磨皮美颜录制?的更多相关文章

  1. Android短视频滑动播放(一)

    本文主要介绍采用RecyclerView配合PagerSnapHelper实现短视频滑动播放内容. 1. 主页内容构建 主页布局文件定义RecyclerView,为RecyclerView建立对应适配 ...

  2. 如何实现 Android 短视频跨页面的流畅续播?

    在一切皆可视频化的今天,短视频内容作为移动端产品新的促活点,受到了越来越多的重视与投入,同时短视频也是增加用户粘性.增加用户停留时长的一把利器.那么如何快速实现移动端短视频功能呢?前两篇我们介绍了盒马 ...

  3. Android短视频SDK转码实践

    一. 前言 一些涉及的基本概念: 转码:一般指多媒体文件格式的转换,比如分辨率.码率.封装格式等: 解复用(demux):从某种封装中分离出视频track和音频track,然后交给后续模块进行处理: ...

  4. 揭秘盒马鲜生 Android 短视频秒播优化方案

    短视频作为内容重要的承载方式,是吸引用户的重点,短视频的内容与体验直接关系到用户是否愿意长时停留.因此,体验的优化就显得尤为重要.上一篇我们分享了 iOS 短视频秒播优化,这篇我们来聊聊 Androi ...

  5. 短视频技术详解:Android端的短视频开发技术

    在 <如何快速实现移动端短视频功能?>中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务.在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术 ...

  6. 短视频图像处理 OpenGL ES 实践

    2017年,短视频正以其丰富的内容表现力和时间碎片化的特点,快速崛起,而短视频最具可玩性之处就在支持人脸识别的动态贴图和各种不同效果的美颜.滤镜等.那短视频动态贴纸.滤镜.美颜等功能究竟是如何实现的呢 ...

  7. 短视频 SDK 架构设计实践

    作者简介 孔维乐,七牛云客户端团队 Android 平台高级开发工程师,专注音视频,图形图像领域.OpenGL 专家,先后参与直播推流及连麦 SDK 的开发,主导短视频 SDK 的架构设计与实现, 对 ...

  8. 最快1天搭建短视频APP!阿里云短视频解决方案上线

    短视频行业的发展前景乐观是毋庸置疑的,整个短视频的市场规模一直在增长,网络数据显示2018年已经突破100亿大关,在2019年预测将超过200亿.那么,对于短视频从业者来讲,要持续推动业务的发展,必须 ...

  9. Android 音视频开发(六): MediaCodec API 详解

    在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...

随机推荐

  1. (让你提前知道软件开发33):数据操纵语言(DML)

    文章2部分 数据库SQL语言 数据操纵语言(DML) 数据操纵语言(Data Manipulation Language,DML)包含insert.delete和update语句,用于增.删.改数据. ...

  2. C# WPF 低仿网易云音乐(PC)歌词控件

    原文:C# WPF 低仿网易云音乐(PC)歌词控件 提醒:本篇博客记录了修改的过程,废话比较多,需要项目源码和看演示效果的直接拉到文章最底部~ 网易云音乐获取歌词的api地址 http://music ...

  3. Expression.Blend.4 Chapter 图片和视频的使用

    原文:Expression.Blend.4 Chapter 图片和视频的使用 翻译的地方可能有错误,欢迎大家指正.但是里面每一个程序都是亲自测试过,并加了点自己的看法. 我翻译的是Expression ...

  4. Win10局域网内无法共享的解决方法分享(开启Server和ComputerBrowser服务,其它文章也不错)

    局域网共享是办公环境下经常使用的,而有些用户反应在升级到win10系统后,网络总是无法共享,给用户带来了很大的困扰,如果你也遇上这样的情况,并通过一些方法无较后,不妨尝试下小编提供的方法. 如果在Wi ...

  5. PO、VO、BO、DTO、POJO、DAO之间的关系

    J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了(听过老罗对这种现象的批判的朋 ...

  6. WPF之动态换肤

    原文:WPF之动态换肤 如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式.窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果:对于简单的换肤操作,如更改 ...

  7. MVC CRUD 的两种方法

    //Index.cshtml @model IQueryable<MvcExam2.Models.Product>@{    Layout = null;}<!DOCTYPE htm ...

  8. 1. linux系统简介

    一.Linux是什么 linux位于系统调用和内核的那两层,直观上来看,我们使用的操作系统还包含一些在其上运行的应用程序,包含文本编译器,浏览器,电子邮件. 二.Linux与windows的区别 1. ...

  9. 微信小程序把玩(六)模块化

    原文:微信小程序把玩(六)模块化 模块化也就是将一些通用的东西抽出来放到一个文件中,通过module.exports去暴露接口.我们在最初新建项目时就有个util.js文件就是被模块化处理时间的 /* ...

  10. 零元学Expression Blend 4 - Chapter 12 用实例了解布局容器系列-「Viewbox」

    原文:零元学Expression Blend 4 - Chapter 12 用实例了解布局容器系列-「Viewbox」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Bl ...