淘拍 |
您所在的位置:网站首页 › 淘拍怎么拍视频 › 淘拍 |
一、前言
首先说说视频剪辑,视频剪辑其实是一个跨终端、跨多个知识栈的横向领域。任何平台任何语言下,只要有足够的计算能力,应该都可以进行视频剪辑。也相信看完这篇文章后,你对于视频的剪辑不会再感觉陌生。 传统的桌面剪辑软件是提供一个GUI界面,给用户提供所见既所得的编辑效果反馈,并在编辑完成之后产生编辑描述数据,最后交由图形图像模块、音频处理模块以及视频编码模块去生成最终视频文件。 参考大部分开源剪辑软件实现,前半部分GUI大部分通过操作系统图形界面或跨平台如QT、SDL、SWT方式实现,这部分我们称之为“前端”。而后面涉及图形图像、音频、编码相关部分,大部分都会有一套媒体编辑内核来支撑,例如Linux下著名的MLT、GStreamer等等,这里我们称之为“编辑内核”。 云剪辑,其实是剪辑端的一种,这里GUI“前端”需要通过浏览器呈现给用户,而“编辑内核”完全可以复用传统的媒体编辑框架。只是在云编辑场景下,“编辑内核”的计算能力是多用户共用,因此需要解决好资源调度问题即可。在Zookeeper、MQ流行的今天,这些调度问题在Java工程师眼里也都不是问题了。 那么云编辑需要解决以下几个问题: 可以描述的渲染效果效果与时间的绑定(非线性)处理逻辑跨平台解决Javascript弱计算能力 二、技术选型视频编辑最核心的3个步骤:1、将媒体文件从视频素材解码出来,2、对解码出来的每帧图片和音频进行处理,3、将处理之后的内容在GUI上展示,或传递给编码器。 在以上 GUI + 编辑内核 的思路之下,看似方案已经很明确,只是这里我们需要确定几件事情。例如GUI如何呈现编辑内核的内容。 我们也看到行业内一些做法: 编辑内核放在云端,通过直播的串流方式推给用户界面编辑内核放在云端,前端GUI只提供少量信息给用户而以上两种方式都存在一些缺陷,例如第一个的延时问题,第二个的缺失所见即所得问题。而整体看Web端侧,基于WebGL、Video Element、Blob、Web Audio、Web worker、Webassembly一系列令人激动的能力,Web已经有了长足的进步。对于在Web侧实现一套编辑内核看起来似乎已经有理论依据。 因此我们确定了一个方向:编辑内核的复用可以共用设计,而不一定追求共用代码。我们先不分平台,设计出内核架构,再看是否可以多平台轻量实现 1、管道回顾上文提到的三个步骤:1、将媒体文件从视频素材解码出来,2、对解码出来的每帧图片和音频进行处理,3、将处理之后的内容在GUI上展示,或传递给编码器。同时考虑到这里的媒体解码除了是通过视频文件,也可以是摄像头采集,或通过类似OpenGL这样的图像库渲染出来的,因此可以把这3个环节抽象出3个核心组件:Producer、Filter、Consumer +-------+ +-------+ +-------+ | | | | |Encoder| |Decoder|-->|Process|-->| | | | | | | GUI | +-------+ +-------+ +-------+ ^ ^ ^ Producer Filter Consumer当Producer和Consumer中存在多个Filter的时候,管道也就产生了 +--------+ +-------+ +-------+ +--------+ |Producer|-->|Filter1|-->|Filter2|-->|Consumer| +--------+ +-------+ +-------+ +--------+这里也涉及管道是Producer推,还是Consumer拉。最终我们选择了Consumer拉的模式,至于原因主要考虑资源利用,因为最终有价值的内容是通过Consumer产出,而底下的Producer无法感知上面的逻辑。 2、裁剪、合并表达裁剪和合并比较容易,对于一段视频会有一个总帧数,而裁剪其实只需记录其开始(in)和结束(out)的时间点即可 +---+-----------------+---+ | x | a | x | +---+-----------------+---+ ^ ^ in out对于合并,更加简单,记录的多段视频的出现顺序即可,为了表示这种排列数据,新建一个模型PlayList +-------+---+-------------+ |a | b |c | +-------+---+-------------+而剪和合都可以抽象的作为一个Producer 3、滤镜滤镜主要是对内容的处理节点,他所处理的位置在Producer和Consumer中间,他是剪辑中重要的一环。这里核心需要实现的是:如何实现一套统一的处理逻辑,在多个端上可以完全重现 +--------+ +------+ +--------+ |Producer|-->|Filter|-->|Consumer| +--------+ +------+ +--------+这里我们选择了专业的图像处理框架OpenGL系,OpenGL、OpenGL ES、WebGL之间的关系如下: 如果要实现统一与平台无关的渲染逻辑,我们需要使用可编程着色器(GLSL),同时考虑多端兼容性,我们选取了OpenGL 2.0 -> OpenGL ES 2.0 -> WebGL 1.0 这条线作为我们的能力集。 4、过渡过渡的效果设计一个视频画面慢慢转化到另一个视频画面,这里就涉及在中间某个时间内,其实有两个视频源。因此需要正式引入多轨道 Multitrack。和Playlist一样Multitrack也是Producer的一种实现。 +--------------------+ +-----------------------+ 0: |a1 | |a2 | +---------------+----+------------------+------+----------------+ 1: |b1 | +------------------------------+轨道可以理解为图片的图层,真实的输出是a1的画面完全叠加在b1之上。当a1没有透明度的情况下,b1在a1结束前是不可见的。 也许这里感觉到多轨道并不能实现过渡效果。因为这里却少了一环,图片混合。 +----------+ |multitrack| | +------+ | +-------------+ +-------+ | |track0|-|--->| |--->|tractor| | +------+ | | | |\ | | | | transitions | | \ | | +------+ | | | | \ | | |track1|-|--->| |--->|---o---|---> | +------+ | +-------------+ | / | | | | / | | +------+ | |/ | | |track2|-|---------------------->| | | +------+ | +-------+ +----------+这里的transitions和滤镜非常类似,通用可以通过GLSL来实现效果的跨平台性,只是滤镜只需要一个纹理输入,而过渡需要两个纹理。同时,过渡是一个时序相关的动作,因此需要有一个时间变量传入,例如过渡开始为0,而过渡结束为1,过渡过程在0-1之间进行。 +--------------------+ +-----------------------+ 0: |a1 | |a2 | +---------------+----+------------------+------+----------------+ 1: |b1 | +------------------------------+ ^ ^ ^ ^ 0 1 0 1 5、动画计算机往往是看起来像什么,而不是是什么。实现动画其实可以参考CSS transition和iOS Core Animation的思路。即记录开始时间和结束时间,物体所在的位置。那么在开始时间和结束时间可以通过算法计算出当前位置。当窗口快速刷新时,看起来物体就进行了移动。 把相同原理应用与大小上,即实现了变大缩少动画,应用于角度上,即实现了旋转。当然这里只有线性变化是通用公示,当非线性动画场景下,如何实现多平台统一呢?答案是给出计算公式,我们使用了开源公式集,包括了easeIn、easeOut、easeInOut等等。 有了以上计算公式,提供开始时间、结束时间、开始状态值、结束时间值,在时间轴内任意一点可计算出当前值,这样既实现了完全平台无关。 6、平台实现到此,基本设计方案都以完成。这里就给各个组件寻找实现方式即可。 Producer:浏览器可以通过Video Element实现,Linux通过FFmpeg的解码函数实现 Consumer:浏览器是提供给用户预览,因此通过Canvas实现,并通过requestAnimationFrame拉取,Linux端负责生成视频,因此使用FFmpeg的编码器实现 滤镜、过渡:基于OpenGL体系,通过GLSL实现,浏览器侧WebGL、Linux侧OpenGL 动画:基于描述语言,浏览器侧通过基于WebGL的pixi.js图像库实现,服务器侧通过QTWebkit内执行pixi.js图像库实现 7、Javascript弱计算能力计算能力其实也可以作为平台特性放到上一节,但这块最为复杂,单独拿出来。 在一些场景下,例如视频的去抖,大部分的去抖算法,需要首先寻找视频中特征点,之后通过OpticFlow算法寻找运动轨迹,之后再通过前后帧数据寻找纠正矩阵,最后进行修正。 这里第一需要大量的CPU计算,第二去抖算法往往由算法团队通过C的动态库或静态库提供。理论上在共用设计的思路下,只要算法确定,可以用JS把算法再实现一次。但是令人遗憾的是JavaScript计算能力太弱,无法满足实时预览。 这里我们使用了Webassembly,在算法团队提供的C++实现上,在进行一轮包装,主要完成JS内图片数据向C数组拷贝和处理结果矩阵的回传工作,之后抖动纠正交由WebGL的纹理+变换矩阵来处理。 三、工程化当所有和视频处理相关的问题都解决的时候,这件事其实已经成了,下面回到我们这些应用工程师的老本行——搭系统、建立模型、链流程。 整体模型主要是Producer、Filter、Transition三个接口,以及他们的若干实现。 视频生成构建3个应用,其中Editor作为淘拍PC的业务应用,对接前台编辑器。Biz对外提供统一视频制作能力整体方案,包括调度、生成、上传、发布。而Core应用作为底层生产单元。可以完成非淘系视频制作任务。 其中Core会JNI调用到媒体框架,依赖ffmpeg、x264、OpenGL、QTWebkit、SOX等,我们将环境打包到Docker里,部署在双显卡的物理机上。并通过Nvidia提供的Docker插件能直接调用到显卡。 前端SDK的部分因为还未对外开放,这里就不展开。 四、最优解行之有效方案的方案就是好方案。但回头反思,他是最优方案吗?可能是、也可能不是。对于当前项目周期和业务目标看他是一个有前提的最优解。但全面来说他还有缺点,这里的跨平台是通过一套描述数据+共用GLSL+共用设计的方式实现。 而全量代码的跨平台应用是否可行呢?比较难,但至少也还是有理论依据。例如,SDL(Simple DirectMedia Layer)内置了与OpenGL的连通,并具备音频处理能力。SDL可以直接跨平台的跑在iOS、Android以及云端编辑后台。而Emscripten编译工具内置了SDL的API实现,将OpenGL映射到WebGL,将音频处理映射到Web Audio,可以完整编译SDL项目到Web端。可能最终的终局是可以实现一份代码,4个端上执行。 但目前看来,该项实现的前期投入成本会非常大。目前我们仅做了少量Demo论证可行性,暂时没有计划实施。 五、最后最后,我们的云编辑平台,首先落在淘拍-电脑版产品中,主要面向商家生产主图视频、包括上面提到的裁剪、合并、滤镜、过渡、字幕、防抖等。其实云编辑的场景不止于此,非常适合制作素材均在云上,只需进行轻量化编辑的场景。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |