作者: 技术产品团队 爱奇艺技术产品团队
转发链接:https://mp.weixin.qq.com/s/nKQG2Sfev58fogfOtqX4Ew
云剪辑是集视频制作、生产、分发等为一体的在线视频制作平台,具备工具及服务两方面能力:工具方面,云剪辑具备全面视频剪辑能力,相比行业中其他在线剪辑工具能力更强大,支持范围包括多轨道音视频合成、音视频素材的裁剪、切割、拖拽,贴片贴字设置和音频编辑等;服务方面,云剪辑平台支持各种业务调用、视频制作和分发以及视频制作状态查询等服务。
图1 爱奇艺云剪辑编辑预览页面
随着Web端技术的不断发展,尤其是HTML5标准的发布和实施,前端不仅能够实现友好的界面展示、交互,还能够实现对流媒体数据的操作和渲染。Web端能力不断的增强,Web应用功能越来越复杂,对性能要求也越来越高。当用桌面软件进行音视频数据的编辑时不仅对机器性能有较高的要求,还耗费大量转码时间。爱奇艺云剪辑则通过Web技术优化实现在线音视频制作,云服务实现转码,有效降低了用户的PC性能要求,还提升了转码性能与速度。
云剪辑的主要功能有:
1、视频剪切、拼接等基础功能
2、视频轨道缩放、拖拽基本交互
3、视频贴字、贴图等基本包装能力
4、视频效果实时预览
5、视频的在线转码能力
这里前面4点都需要在浏览器端完成,基于Web技术在浏览器端实现类似桌面的大型编辑软件有很多技术难点:
首先,如何在Web实现模拟播放,实现所见即所得;
其次,在Web端进行复杂的操作时,浏览器资源消耗较大,如何保证良好的交互体验和性能;
再有,视频制作除了剪切与拼接外,如贴字、贴图、滤镜等效果叠加,也需要浏览器端来进行模拟,且需要与服务端保持一致,这也是一个技术难点。
下面我们来看下爱奇艺技术团队如何通过Web技术在云剪辑中实现在线的音视频编辑的。
云剪辑把PC桌面程序的功能迁移到云端。本来在一台计算机上运行的程序,现在由多台计算机分别完成。之前由一个程序不同模块执行的计算,现在通过网络相连的不同的服务协调完成。这就给云剪辑的架构设计带来了很大的挑战。
如图2所示,爱奇艺云剪辑整体架构分为四个部分:
图2 爱奇艺云剪辑整体架构图
Web客户端:负责与用户的具体交互操作,包括素材导入、视频剪辑和效果实时预览。具体功能可参考图3。
Node中间层:主要功能为项目和视频数据接收、转发、保存等。
创作中台:为云剪辑提供视频制作、转码、分发等业务处理和调度。
云平台:提供基础支撑,如音视频转码、存储分发等。
图3 Web端产品架构图
视频剪辑效果的实时预览,成为云剪辑工具的一个技术难点。爱奇艺云剪辑播放器,创造性的通过多个播放器实例组合接力的模式,实现了多个视频裁剪、切割、拼接后实时预览的目的。剪辑预览播放器的原理如图4所示:
图4 剪辑预览播放器原理图
多个视频播放器实例组合成为一个视频播放器,使用canvas投影整合视频画面。那么要解决下面的问题:
2.1. 多组视频播放器以及播放次序组织问题
将视频播放器的实例分别放入不同的视频小组中。视频小组是视频整合的更高一级虚拟形式。每个视频小组中,加入数量不等的视频实例,视频小组分工不同,有的小组负责预加载,有的小组负责投影,有的小组负责转换。视频小组互相补充,互相接力,又互相制约,通过这种方式将有效解决视频拼接播放流畅性的问题。
2.2. 视频在切换、跳转时如何保证待播的资源准备得当
当视频跳转(seek)播放时,不能预测用户要播放哪个视频的哪个片段,也就谈不上提前准备资源了。但是我们经过大量的实际验证发现,打造一个专门用来缓存历史数据的视频小组,能有效提高命中预加载视频的几率。所以将其他视频小组中暂时不用的资源聚合到缓存视频小组,缓存视频小组再通过自己灵活介入的优势,将缓存数据最大限度的复用,这样就最大限度的解决跳转播放时出现的卡顿现象。具体流程如图5所示:
图5 预览播放器流程图
利用多个视频实例组合播放,对视频格式有比较好的兼容性与稳定性。通过分组的方式整合播放资源,有效的提升了资源的利用率,降低了内存占用。
解决了视频预览的问题,还要加入各种各样的包装定制和特效功能,因为云剪辑的预览播放器画面是投影在canvas元素上的,这就给我们的视频包装留下了很大的发挥空间。视频包装流程如图6所示。
图6 包装流程图
基于播放器组合接力原理以及包装定制等能力,云剪辑播放器实现了视频剪辑的实时预览功能,且效果与云端转码效果一致。同时从高性能、可维护性等角度出发,我们对播放器架构按播放控制、核心、包装进行分层设计。图7是剪辑预览播放器的整体架构图。
图7 剪辑播放器架构图
视频制作本身是用户与工具强交互的行为。云剪辑是一个在线视频制作工具,相比桌面程序的劣势主要在性能与交互上,其中视频剪辑轨道是视频制作工具Web化的难点。在实现复杂的、可定制化的视频制作功能的基础上,还要保证操作流畅性。我们通过功能分层与结构优化等多种方式来解决这些问题,图8是剪辑轨道整体的功能架构图:
图8 剪辑轨道架构图
剪辑轨道需求在各个视频剪辑任务中差别较大,有的只需要视频轨道,有的需要视频和音频轨道,有的需要简单的包装或者贴图轨道。基于视频剪辑的多元化的需求,我们需要将轨道部分打造成可定制化的组件。众多的组件和复杂的交互使得代码结构是否合理就非常必要,因此我们对组件的开发方式和结构均进行了整理。图9是剪辑轨道简化后的代码结构图:
图9 代码结构图
结构的清晰保证了大型复杂程序的可扩展性和可维护性,也保证了多元化的业务需求得到满足。
Node是前端与后端之间的桥梁
我们会通过Node中间层来解决接口整合、临时数据存储、前后端交互的数据一致性等问题。对于后端来说,只需提供原始数据而不必过多关注前端对接口数据格式的要求,更加专注于自身业务。对前端来说,获得了定制化的接口数据,也能够减少前端发起请求的次数。云剪辑中间层架构如下图10所示:
图10 爱奇艺云剪辑中间层架构图
其中Nginx转发无需经过中间层处理的请求,提供静态资源服务。Node处理业务逻辑,负责与创作平台的交互。云剪辑中间层采用了自研的qiyi-wings框架,在Koa2的基础上,划分了router、controller、service、model、dao等层次。业务模块之间相互分离,模块内部按层次划分。代码架构如下图11所示:
图11 中间层代码架构图
我们通过Web端系统与代码架构设计解决数量庞大的前端代码带来的代码维护与可扩展性问题。
5.1. Web端系统架构
在云剪辑工具中,用户需要在轨道上对素材进行剪裁、拼接、调整出入点、修改倍速等一系列操作,最后在播放器中预览成片。在整个操作过程中,平台定时保存视频中间态到服务端数据库。当页面刷新时,从服务端获取中间态恢复视频,支持继续编辑。
图12 数据流程图
如图12所示,云剪辑工具提供海量的音视频素材以及多种多样的文字模板,
云剪辑工具以轨道数据为中心,轨道数据一旦发生变化(素材拖拽到轨道、轨道内操作素材、配置区修改素材),会触发数据分发流程,轨道将自身数据分发到播放器、特效包装层、素材配置区,这些模块将分发的数据经过处理,转化为自身需要的格式展示出来。以轨道数据为中心的机制使得轨道可支持全局范围内的撤销重做,不仅仅是轨道上的修改。
5.2. Web前端代码架构
云剪辑前端工程是基于Vue+QUI2.0搭建的,QUI2.0是爱奇艺前端团队孵化出来的组件库。它是基于Vue的Web端开发套件,旨在为企业级应用开发提供统一的前端解决方案,包括基础组件、工程框架和工具命令等。前端工程是包含多个模块的单页面应用。src目录下的代码结构如下图13所示。
图13 前端代码结构图
其中editor模块按照功能划分为六部分,项目配置区project,素材区material,轨道区track,播放器区video,装饰器特效区decorator,视频发布区forms。每个部门有相应的store存储数据,实现数据统一管理与共享。
前端工程请求服务端数据的流程如下图14。
图14 前端数据流程图
通过结构化的代码分层、严格的流程控制、精细的交互设计,利用Web技术实现了复杂的音视频编辑。随着Web技术的不断发展与完善,其性能与交互也将越来越接近甚至超越桌面程序。云剪辑的Web端架构也会随着时代不断进步,后续我们也将引入Web Assembly实现解码和计算,引入AI技术为视频赋能等。目前爱奇艺云剪辑只提供给爱奇艺内部的制作团队使用,未来将对外开放,为外部工作室、小团队、个人制作者提供高效便捷的创作能力,让大家享用Web+云服务+AI技术的便利,有效降低视频创作门槛,提高制作生产效率。
《我再也不敢说我会写前端 Button组件「实践」》
《NodeX Component - 滴滴集团 Node.js 生态组件体系「实践」》
《Node Buffers 完整指南》
《推荐18个webpack精美插件「干货」》
《前端开发需要了解常用7种JavaScript设计模式》
《浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务》
《了不起的 Webpack HMR 学习指南(上)「含源码讲解」》
《了不起的 Webpack HMR 学习指南(下)「含源码讲解」》
《10个打开了我新世界大门的 WebAPI(上)「实践」》
《10个打开了我新世界大门的 WebAPI(中)「实践」》
《10个打开了我新世界大门的 WebAPI(下)「实践」》
《「图文」ESLint 在中大型团队的应用实践》
《Deno是代码的浏览器,你认同吗?》
《前端存储除了 localStorage 还有啥?》
《Javascript 多线程编程的前世今生》
《微前端方案 qiankun(实践及总结)》
《「图文」V8 垃圾回收原来这么简单?》
《Webpack 5模块联邦引发微前端的革命?》
《基于 Web 端的人脸识别身份验证「实践」》
《「前端进阶」高性能渲染十万条数据(时间分片)》
《「前端进阶」高性能渲染十万条数据(虚拟列表)》
《图解 Promise 实现原理(一):基础实现》
《图解 Promise 实现原理(二):Promise 链式调用》
《图解 Promise 实现原理(三):Promise 原型方法实现》
《图解 Promise 实现原理(四):Promise 静态方法实现》
《实践教你从零构建前端 Lint 工作流「干货」》
《高性能多级多选级联组件开发「JS篇」》
《深入浅出讲解Node.js CLI 工具最佳实战》
《延迟加载图像以提高Web网站性能的五种方法「实践」》
《比较 JavaScript 对象的四种方式「实践」》
《使用Service Worker让你的 Web 应用如虎添翼(上)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(中)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(下)「干货」》
《前端如何一次性处理10万条数据「进阶篇」》
《推荐三款正则可视化工具「JS篇」》
《如何让用户选择是否离开当前页面?「JS篇」》
《JavaScript开发人员更喜欢Deno的五大原因》
《仅用18行JavaScript实现一个倒数计时器》
《图文细说JavaScript 的运行机制》
《一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索》
《推荐Web程序员常用的15个源代码编辑器》
《10个实用的JS技巧「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」》
《深入JavaScript教你内存泄漏如何防范》
《手把手教你7个有趣的JavaScript 项目-上「附源码」》
《手把手教你7个有趣的JavaScript 项目-下「附源码」》
《JavaScript 使用 mediaDevices API 访问摄像头自拍》
《手把手教你前端代码如何做错误上报「JS篇」》
《一文让你彻底搞懂移动前端和Web 前端区别在哪里》
《63个JavaScript 正则大礼包「值得收藏」》
《提高你的 JavaScript 技能10 个问答题》
《JavaScript图表库的5个首选》
《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》
《可视化的 JS:动态图演示 - 事件循环 Event Loop的过程》
《教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」》
《可视化的 js:动态图演示 Promises & Async/Await 的过程》
《原生JS封装拖动验证滑块你会吗?「实践」》
《如何实现高性能的在线 PDF 预览》
《细说使用字体库加密数据-仿58同城》
《Node.js要完了吗?》
《Pug 3.0.0正式发布,不再支持 Node.js 6/8》
《纯JS手写轮播图(代码逻辑清晰,通俗易懂)》
《JavaScript 20 年 中文版之创立标准》
《值得收藏的前端常用60余种工具方法「JS篇」》
《箭头函数和常规函数之间的 5 个区别》
《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》
《「前端篇」不再为正则烦恼》
《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》
《深入细品浏览器原理「流程图」》
《JavaScript 已进入第三个时代,未来将何去何从?》
《前端上传前预览文件 image、text、json、video、audio「实践」》
《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》
《推荐13个有用的JavaScript数组技巧「值得收藏」》
《前端必备基础知识:window.location 详解》
《不要再依赖CommonJS了》
《犀牛书作者:最该忘记的JavaScript特性》
《36个工作中常用的JavaScript函数片段「值得收藏」》
《Node + H5 实现大文件分片上传、断点续传》
《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》
《【实践总结】关于小程序挣脱枷锁实现批量上传》
《手把手教你前端的各种文件上传攻略和大文件断点续传》
《字节跳动面试官:请你实现一个大文件上传和断点续传》
《谈谈前端关于文件上传下载那些事【实践】》
《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》
《最全的 JavaScript 模块化方案和工具》
《「前端进阶」JS中的内存管理》
《JavaScript正则深入以及10个非常有意思的正则实战》
《前端面试者经常忽视的一道JavaScript 面试题》
《一行JS代码实现一个简单的模板字符串替换「实践」》
《JS代码是如何被压缩的「前端高级进阶」》
《前端开发规范:命名规范、html规范、css规范、js规范》
《【规范篇】前端团队代码规范最佳实践》
《100个原生JavaScript代码片段知识点详细汇总【实践】》
《关于前端174道 JavaScript知识点汇总(一)》
《关于前端174道 JavaScript知识点汇总(二)》
《关于前端174道 JavaScript知识点汇总(三)》
《几个非常有意思的javascript知识点总结【实践】》
《都2020年了,你还不会JavaScript 装饰器?》
《JavaScript实现图片合成下载》
《70个JavaScript知识点详细总结(上)【实践】》
《70个JavaScript知识点详细总结(下)【实践】》
《开源了一个 JavaScript 版敏感词过滤库》
《送你 43 道 JavaScript 面试题》
《3个很棒的小众JavaScript库,你值得拥有》
《手把手教你深入巩固JavaScript知识体系【思维导图】》
《推荐7个很棒的JavaScript产品步骤引导库》
《Echa哥教你彻底弄懂 JavaScript 执行机制》
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《深入解析高频项目中运用到的知识点汇总【JS篇】》
《JavaScript 工具函数大全【新】》
《从JavaScript中看设计模式(总结)》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《浏览器中实现JavaScript计时器的4种创新方式》
《Three.js 动效方案》
《手把手教你常用的59个JS类方法》
《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》
《深入浅出讲解 js 深拷贝 vs 浅拷贝》
《手把手教你JS开发H5游戏【消灭星星】》
《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》
《手把手教你全方位解读JS中this真正含义【实践】》
《书到用时方恨少,一大波JS开发工具函数来了》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《手把手教你JS 异步编程六种方案【实践】》
《让你减少加班的15条高效JS技巧知识点汇总【实践】》
《手把手教你JS开发H5游戏【黄金矿工】》
《手把手教你JS实现监控浏览器上下左右滚动》
《JS 经典实例知识点整理汇总【实践】》
《2.6万字JS干货分享,带你领略前端魅力【基础篇】》
《2.6万字JS干货分享,带你领略前端魅力【实践篇】》
《简单几步让你的 JS 写得更漂亮》
《恭喜你获得治疗JS this的详细药方》
《谈谈前端关于文件上传下载那些事【实践】》
《面试中教你绕过关于 JavaScript 作用域的 5 个坑》
《Jquery插件(常用的插件库)》
《【JS】如何防止重复发送ajax请求》
《JavaScript+Canvas实现自定义画板》
《Continuation 在 JS 中的应用「前端篇」》
作者: 技术产品团队 爱奇艺技术产品团队
转发链接:https://mp.weixin.qq.com/s/nKQG2Sfev58fogfOtqX4Ew