短视频技术详解:Android端的短视频开发技术
在 《如何快速实现移动端短视频功能?》中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务。在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术。
推荐阅读
《如何快速实现移动端短视频功能?》
短视频业务主要包含:“视频录制”以及 “视频编辑”这两个核心功能。
其中视频录制又包括:视频采集、实时美颜、自定义码率、摄像头切换、变焦、对焦、曝光度调节以及滤镜等功能。
视频编辑包括:视频裁剪、视频拼接、混音、视频动画效果、动态贴图等功能。
Android端短视频录制的技术方案
我们先来说说视频录制:
视频录制的大致实现流程就如上图所示,先由Camera、AudioRecord进行最原始的相机画面以及声音的采集,然后将采集的数据进行滤镜、降噪等前处理,处理完成后由MediaCodec进行硬件编码,最后采用MediaMuxer生成最终的MP4文件。
这个方案的优点在于,由于全程采用了GPU以及硬件编码,基本上不涉及CPU上的操作,因此可实现在高帧率(30fps)、高分辨率(720P)以及高码率的情况下CPU暂用率也非常低,即使在性能较差的手机上也能很好的运行。但同时这个方案的难点也在于此。
做过音视频的同学都知道,通常情况下我们所说的对音视频的处理,主要是对视频的 YUV、H264 音频的PCM、AAC这类数据格式进行操作,这类操作都有相关的RFC技术也比较成熟,实现起来比较容易,出了问题也更容易定位,通常情况下在PC等设备上也都是这么处理的。
但这样的方案在对于手机端情况就不同了,虽然手机这几年的性能大大加强了,很多旗舰手机基本都是8核的CPU了,但要操作如此大量的图片数据并进行浮点运算对CPU的消耗还是很大的。CPU暂用率高就会引起手机发烫,手机发烫就会导致Camera采集的掉帧,甚至在一些小米等厂商下,手机发烫还会引起CPU降频,CPU一降频那APP所暂用的CPU比例就更高了,同时CPU暂用率高电量消耗就快。
因此上面的方案是目前Android上比较适合短视频录制的方案。
Android端短视频录制的具体实现
既然确定了技术方案,我们就来看看具体的实现。这里首先需要知道几个概念:
SurfaceTexture
我们知道在一些简单的自定义相机应用中,要实现一个相机,只需要将一个SurfaceHolder设置给Camera,Android系统就会自动的帮我们把Camera采集的数据绘制到屏幕上。但由于在短视频中我们需要对相机采集的数据进行前处理加工比如滤镜等,而且还要做到可见即所得的效果,因此必须要求我们将相机采集的数据先缓存起来,前处理完后自己再绘制到屏幕上,这时候就需要用到SurfaceTexture了。按照Android官方文档的介绍,SurfaceTexture就是这样一块用于接收Camera采集的数据,同时又不可见的画布。这块画布是存在于GPU内存中的。
TextureID
纹理ID,主要用来标识每一块纹理在GPU内存中的内存地址,类似于C语言中的内存指针。每一块GPU的纹理(可以理解为一块用于显示图片的画布)都有对应的一个TextureID进行标识。上述的SurfaceTexture在创建也同样需要绑定一个纹理ID进行唯一标识。
知道了这两个概念,我们就知道了Camera采集的数据具体存在于GPU的哪个位置了。接下来就可以对原始的数据进行前处理编码了。
这里有一个需要注意的地方,Android的camera采集到SurfaceTexture上的纹理是GL_TEXTURE_EXTERNAL_OES 类型的纹理,而目前市面的很多滤镜算法,如开源的GPUImage中很多的滤镜都是基于GL_TEXTURE_2D类型的纹理进行图像处理的。
因此在进行我们在基于开源滤镜算法或自研算法时需要先将GL_TEXTURE_EXTERNAL_OES类型的纹理转化为GL_TEXTURE_2D的纹理,或者在GPU Shader中加入 "#extension GL_OES_EGL_image_external: require" 来表明该纹理是OES纹理,同时编写基于OES纹理的图像处理算法。
目前网易这边是先将OES转化为TEXTURE_2D在进行前处理,这样便于与iOS端算法统一以及更好的接入一些开源的滤镜算法。
解决了SurfaceTexture的问题,接下来的MediaCodec以及MediaMuxer就比较容易了。Android中的MediaCodec天生支持将GPU中的纹理绘制到MediaCodec的Surface中,然后对Surface中的图像直接进行硬件编码,图像数据始终是在GPU空间中进行流转,而没有涉及到CPU。
这里需要注意的是MediaCodec以及MediaMuxer需要在API 18及以上才能使用。同时需要注意MediaCodec在不同设备上的兼容性。
Android端视频编辑功能
最后对于视频编辑的功能,目前Android上没有很好的系统API即硬件处理方式,主要还是利用ffmpeg进行相应的叠加、裁剪混音等后期处理。可以优化的一个点是,先将原始的MP4视频进行解码,然后将解码后的YUV数据映射到GPU的纹理上进行亮度、饱和度等参数的调节,做到文件编辑的所见即所得,然后将调好的参数配置为ffmpeg进行编辑处理。
想要获取更多产品干货、技术干货,记得关注网易云信博客。
短视频技术详解:Android端的短视频开发技术的更多相关文章
- 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...
- P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...
- 「视频直播技术详解」系列之七:直播云 SDK 性能测试模型
关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 本系列文章大纲如下: ...
- Comet技术详解:基于HTTP长连接的Web端实时通信技术
前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...
- Python开发技术详解(视频+源码+文档)
Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...
- IPv6技术详解:基本概念、应用现状、技术实践(下篇)
本文来自微信技术架构部的原创技术分享. 1.前言 在上篇<IPv6技术详解:基本概念.应用现状.技术实践(上篇)>,我们讲解了IPV6的基本概念. 本篇将继续从以下方面展开对IPV6的讲解 ...
- IPv6技术详解:基本概念、应用现状、技术实践(上篇)
本文来自微信技术架构部的原创技术分享. 1.前言 普及IPV6喊了多少年了,连苹果的APP上架App Store也早已强制IPV6的支持,然并卵,因为历史遗留问题,即使在IPV4地址如果饥荒的情况下, ...
- 手游录屏直播技术详解 | 直播 SDK 性能优化实践
在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...
- SSE技术详解:一种全新的HTML5服务器推送事件技术
前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...
随机推荐
- NP、NP-完全、NP-难问题
What are the differences between NP, NP-Complete and NP-Hard? 0. 基本定义 判定问题(decision problem):一个答案是是或 ...
- Python Numpy基础教程
Python Numpy基础教程 本文是一个关于Python numpy的基础学习教程,其中,Python版本为Python 3.x 什么是Numpy Numpy = Numerical + Pyth ...
- 距离北京奥运还有359天,发布WPF版本的北京2008标志(下)
原文:距离北京奥运还有359天,发布WPF版本的北京2008标志(下) 图片显示效果: XAML代码: <Viewbox Width="463.548828" Height ...
- WPF无边框捕获消息改变窗口大小
原文:WPF无边框捕获消息改变窗口大小 文章大部分转载自http://blog.csdn.net/fwj380891124,如有问题,请联系删除 最近一直在学习 WPF,看着别人做的WPF程序那么漂 ...
- Codeforces 35E Parade 扫描线 + list
主题链接:点击打开链接 意甲冠军:特定n矩阵(总是接近底部x轴) 然后找到由上面的矩阵所包围的路径,的点 给定n 以下n行给定 y [x1, x2] 表示矩阵的高度和2个x轴坐标 思路: 扫描线维护每 ...
- Nucleus PLUS系统架构和组件
(一个)方法论和软件组件 1.软件组件(Software Component)定义 从一般意义上来说.组件(Component)是系统中能够明白辨识的组成部分,一个不透明的功能实现体.软件开发中,组件 ...
- Visifire charts AxisLabels FontSize
<charts:Chart.AxesX> <charts:Axis LineThickness="0.25" > <charts:Axis.AxisL ...
- QWidget继承自QPaintDevice,这样就可以直接把QWidget传入QPainter的构造函数,比如QPainter(mylabel),然后设置QWidget的长宽后直接进行作画了
比如用QLabel在主界面上画两条虚线: bool ContentWidget::eventFilter(QObject *obj, QEvent *event) { if(obj == line_l ...
- 修改window.external使JS可调用Delphi方法
原文地址:http://hi.baidu.com/rarnu/blog/item/4ec80608022766d663d986ea.html 在js中,有一个比较特殊的对象,即window.exter ...
- ES6/ES2015核心内容(转载)
ES6其实就是ES2015,因为是2015年发布的,所以也叫ES2015.这个版本是JS的最新版本,很多浏览器还不支持,所有有了babel,专门把最新的JS转换一下,让大部分浏览器都支持的JS版本. ...