淘拍-视频云剪辑,我们这样做
一、前言
首先说说视频剪辑,视频剪辑其实是一个跨终端、跨多个知识栈的横向领域。任何平台任何语言下,只要有足够的计算能力,应该都可以进行视频剪辑。也相信看完这篇文章后,你对于视频的剪辑不会再感觉陌生。
传统的桌面剪辑软件是提供一个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论证可行性,暂时没有计划实施。
五、最后
最后,我们的云编辑平台,首先落在淘拍-电脑版产品中,主要面向商家生产主图视频、包括上面提到的裁剪、合并、滤镜、过渡、字幕、防抖等。其实云编辑的场景不止于此,非常适合制作素材均在云上,只需进行轻量化编辑的场景。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring Boot是如何实现自动配置的
Spring Boot 是 Spring 旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot 的特点可以概述为如下几点: 内置了嵌入式的 Tomcat、Jetty 等 Servlet 容器,应用可以不用打包成War 格式,而是可以直接以 Jar 格式运行。 提供了多个可选择的 ”starter ” 以简化Maven的依赖管理(也支持Gradle),让您可以按需加载需要的功能模块。 尽可能地进行自动配置,减少了用户需要动手写的各种冗余配置项,Spring Boot 提倡无XML配置文件的理念,使用Spring Boot生成的应用完全不会生成任何配置代码与XML配置文件。 提供了一整套的对应用状态的监控与管理的功能模块(通过引入spring-boot-starter-actuator),包括应用的线程信息、内存信息、应用是否处于健康状态等,为了满足更多的资源监控需求,Spring Cloud中的很多模块还对其进行了扩展。 有关Spring Boot的使用方法就不做多介绍了,...
- 下一篇
EdgeX Foundry理论篇
总体架构 核心服务层 核心数据微服务 搜集持久化设备和传感器等边缘设备数据,支持导出到云。目前,数据本地存储交互通过REST APIs,未来会支持更多协议:MQTT, AMQP等。数据导出到Export Service layer,通过ZeroMQ、MQTT。persist.data=false,数据不存核心数据,直接通过消息队列到达Export Service layer。本服务是唯一能获得设备数据的服务。查询数据流程图添加属性流程图 命令微服务 负责把命令从北端传到南端,不允许非法命令与设备交互。命令主要来自一下:其他微服务命令(本地边缘数据分析、规则引擎微服务)、其他应用命令(系统管理agent关闭一个设备)和外部系统命令(修改一系列设备设置文件)。命令微服务提供统一规范方式与设备通信,GET命令获取设备数据;PUT命令下发action或下发配置数据。命令微服务通过设备服务同设备交互,不直接交互设备。查询命令流程图发送命令流程图 元数据微服务 元数据微服务主要包括管理设备配置文件,包括设备信息、设备数据结构类型和设备命令。每个被EdgeX 管理的设备,都在元数据有关联ID,设备关...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS关闭SELinux安全模块
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合Redis,开启缓存,提高访问速度
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程