小白相机的视频生成方案

小白相机的视频生成方案

做为一款相机,为用户提供一些酷炫的视频特效自然是主要功能之一,小白相机也不例外。

从这个需求的提出到方案选型确认,再到最终的实现和完善,经历了一些重要和有趣的过程,特在此分享,希望能引起大家的思考。

需求的提出

产品的最终目的是让用户都来使用小白相机,而能抓住用户的需求和兴趣点无疑是提高新用户数据和老用户留存的关键所在。基于此产品给我们提出的需求主要概括为以下三点:

  1. 多样的特效:设计的特效模板使用的After Effect来进行制作模板,如此专业的工具可以做出多种多样的特效,产品要求用户制作的视频的效果尽可能地与使用AE渲染出来的一致。
  2. 快速上线的模板:持续更新和添加的模板有助于提高用户的粘性,所以快速上线新的模板成了必然的需求。
  3. 小程序中可用:这就要求我们不能使用客户端的渲染技术,要么前端渲染要么服务端渲染。


小白魔法照片





方案讨论和确定

做为一个PHP工程师,基本没有接触过视频处理的,刚接到需求时多少有点不知道所措。经过调研,刚开始提出了一些可选的方案:

  1. 前端使用CSS和JS实现特效:这个方案的缺点很明显,生成出来的最终结果不是一个视频,用户无法下载;而且每一个新的模板都要前端开发,耗费人力和时间。
  2. 使用MLT Multimedia Framework等开源的工具来开发模板,实现服务端渲染视频:这个方案会优于前端的方案,至少生成了视频,而且MLT提供的灵活度也可以实现大部分AE的功能。但也有一个缺点,需要先将AE的特效转成MLT的XML格式后才能服务端渲染生成视频,这给技术和设计师所带来的压力和工作量都不小。

这两个常规的方案经过一番讨论下来都无法令各方接受,所以我们可能要另外想想一些非常规的解决方案了。

在研究AE的特效过程中,我们无意间留意到了AE其实提供了一个命令行程序aerender.exe,进一步查看官方文档,发现aerender.exe可以使用项目工程自动化渲染结果!灵光一现,是否可以通过用户上传资源后使用aerender.exe来自动渲染生成视频呢?

经过调研测试运行,这个方案基本上可行,而且很好地符合了产品的需求,对人力的需求也减轻了。于是我们就按这个方案进行实现和部署。

AE简介

AE是Adobe After Effects的简称,Adobe After Effects主要用于创建动态图形和视觉特效。允许使用者以2D或3D中的各种内建工具和第三方插件(插件)创建动画。After Effects是基于非线性编辑的软件,透过“层”控制音讯与影片的合成,这意味着每个单独的媒体对象(影片剪辑,音讯剪辑,静态图像等)都有自己独立的轨道。与此相反的,一些其他的非线性编辑系统使用另一种模式,即只要媒体对象在时间上不重叠,不同的媒体对象都可以占用相同的轨道,这种方式可以保持专案档案的简洁。After Effects采用的层系统广泛的应用关键帧。虽然其他合成软件,特别是那些采用树状或节点的工作模式(如Nuke),更适合管理大量的素材,但是After Effects能够透过有选择性地隐藏层或分组来管理有点杂乱的轨道。

Ffmpeg简介

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

流程

以下的流程图

整体流程分成4步

  1. 用户端(小程序/APP):用户在前端选择模板后,根据模板所需要的素材上传对应的小视频或者图片;上传完成之后调用服务端接口。
  2. 服务端(nginx+php):服务端接收用户请求,做入库等业务逻辑处理,并产生一条渲染任务,推送到消息队列中。
  3. 渲染服务(windows+go):渲染服务消费消息队列获取任务;分析任务的信息加载模板和素材,渲染成视频,并将此结果推送到消息队列
  4. 服务端(php):消费结果队列,将生成的视频信息推送到用户端,其中会有超时及重试机制,至此整个过程完成。

除了渲染服务外,其它的都是常规的服务;所以接下介绍一下渲染服务的工作机制和流程。

视频的生成

渲染任务的消息主要有以下几个信息

  1. 模板id
  2. 用户上传的素材,每一个模板需要的素材不一样,所以素材数量和种类是与模板一一对应的
  3. 用户的相关信息,写回结果时的处理

go程序的处理过程

  1. 下载对应的模板内容,其实就是AE的项目文件
  2. 将模版copy新的工作区(为了可以实现多任务渲染),使用用户的素材替换AE项目下的模板素材文件
  3. 调用aerender.exe渲染成视频

可执行文件 aerender.exe 是具有命令行接口的程序,可用于自动执行渲染。您可以使用 aerender应用程序在多个属于渲染场一部分的计算机上执行渲染操作,也可以在作为批操作一部分的单台计算机上使用 aerender 应用程序。可以通过在命令行上(或批处理脚本中)输入命令 aerender,后跟一系列可选参数,来使用该程序。有些参数是本身不带任何参数的简单选项(例如 -reuse),而有些参数则带有它们自己的参数(例如 -project project_path)。
将 Composition_1 渲染到指定的文件,请输入此命令:

aerender -project c:\projects\project_1.aep -comp "Composition_1" -output c :\output\project_1\project_1.avi

这样视频就生成完成了,将完成的视频上传到cdn,并将对应的链接返回给PHP处理,这样整个处理就已完成了。

但这样有几个问题

  1. 渲染太慢,一个10秒的模板一次需要30来秒才能渲染完成
  2. 渲染生成的视频太大,因为AE本身带的编码压缩并不能很好的控制视频的大小
  3. 产品上还需要指定帧的画面做为封面

优化渲染慢的问题

比如一个10秒180帧的视频,我们可以分成5个36帧的分段视频来渲染

分片渲染,将 project_1.aep 中的 Composition_1 的第 1 到第 36 帧渲染到指定的文件,留意以下的-s和-e参数:

aerender.exe -project c:\projects\project_1.aep -comp "Composition_1" -s 1 -e 36 -RStemplate "Multi-Machine Settings" -OMtemplate "Multi-Machine Sequence" -output c:\output\project_1\frames_1.mov

这样之后就会生成5个分段的小视频,需要将这5个小视频合并成一个完整视频,我们使用的是FFmpeg,具体流程是:

建立一个文档,比如file.txt ,位置c:\output\project_1\file.txt, 里面内容,一个file,占用一行

1 file "c:\output\project_1\frames_1.mov"
2 file "c:\output\project_1\frames_1.mov"
3 file "c:\output\project_1\frames_1.mov"

连接视频

ffmpeg -f concat -i "c:\output\project_1\file.txt" -c copy "c:\output\project_1\outmerge.mov";

注意一点。在这里合并视频的所有的视频片段的格式、分辨率、码率都得是一样的,否则视频很容易失败,因为中间我们省去一个转码的过程,如果要转码成统一的格式,对服务器的开销很大,但还是可以实现的,这涉及的知识就更多了,这里的合并只针对相同的格式、分辨率的视频的合并。

使用ffmpeg压缩转码视频

有的视频,如一些视频学习教程通常画面都是不大变化的,和变动速度快的打斗视频所需要的帧数完全不同,音质要求也不是很高。可以采用降低fps和音频码率的方法大大压缩文件大小,而清晰度不变!
通常转成.mp4,采用H.264视频压缩算法和AAC音频压缩算法,视频帧率18fps,音频码率32k

1ffmpeg -i c:\output\project_1\outmerge.mov -c:v libx264 -pix_fmt yuv420p c:\output\project_1\out.mp4

接下来的工作

  1. windows的集群化管理
  2. 性能上如何提升
  3. 模板的生成问题
  4. 其他更成熟的方案

我们是花椒技术,如果想了解更多内容请关注我们的公众号:花椒技术

发布于 2019-07-09

文章被以下专栏收录

    随着微信的普及,即时通讯中的文本聊天和语音、视频通话已经在生活的各个方方面面有所体现。 类微信应用、泛娱乐社交、直播等场景都是借助于沟通而产生了更多的交互场景。 在音视频和IM这个领域,到底有哪些坑,有哪些雷是可以避免的? 请,跟我一起来,解答你的疑问和困惑,帮助你的产品快速孵化和上线。